搜索
bottom↓
回复: 9

请教关于IAR的位操作

[复制链接]

出0入0汤圆

发表于 2012-8-21 19:58:53 | 显示全部楼层 |阅读模式
开始我不知道IAR能位操作所以我都是这么操作:
#define  DCLK_H     P6OUT|=(1<<0)
#define  DCLK_L     P6OUT&=~(1<<0)
#define  CS_H       P6OUT|=(1<<1)
#define  CS_L       P6OUT&=~(1<<1)
#define  DIN_L      P6OUT|=(1<<2)
#define  DIN_H      P6OUT&=~(1<<2)
#define  BUSY_OK       P6IN&0x08    //为0表示不繁忙可读数据
#define  DOUT       P6IN&0x10     //触摸屏的数据输出
#define  Penirq     P6IN&0x20    //触碰触摸屏时,ADS7843Penirq引脚由未触摸时的高电平变为低电平
但是发现总是运行结果不对,后来我先定义:
//P6口输出数据
#define P6                       P6OUT
#define P60                      P6OUT_bit.P6OUT_0
#define P61                      P6OUT_bit.P6OUT_1
#define P62                      P6OUT_bit.P6OUT_2
#define P63                      P6OUT_bit.P6OUT_3
#define P64                      P6OUT_bit.P6OUT_4
#define P65                      P6OUT_bit.P6OUT_5
#define P66                      P6OUT_bit.P6OUT_6
#define P67                      P6OUT_bit.P6OUT_7
然后定义:
#define DCLK         P60   
#define CS       P61
#define DIN      P62
#define BUSY     P63       
#define DOUT     P64                                                                                                                                                                                  
#define Penirq   P65   //触碰触摸屏时,ADS7843Penirq引脚由未触摸时的高电平变为低电平



程序中直接DCLK=0 DCLK=1这样用 发现运行结果正确了,请教高手这两种方法有什么不同吗?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2012-8-26 19:24:05 | 显示全部楼层
顶一下了。。。。

出110入109汤圆

发表于 2012-8-26 21:21:44 | 显示全部楼层
但是发现总是运行结果不对,后来我先定义
--------------------------------------------------------------
开始的定义形式是通用的,咋会出错呢?

出0入8汤圆

发表于 2012-8-26 21:54:56 | 显示全部楼层
reflecter 发表于 2012-8-26 21:21
但是发现总是运行结果不对,后来我先定义
------------------------------------------------------------- ...

是呀  第一种定义方式 最通用了。 怎么会出错  即使出错了也要找找原因啊。

出0入0汤圆

发表于 2012-8-26 22:44:01 | 显示全部楼层
这个。。。
把P6OUT|=(1<<0)改成P6OUT|=0x01会好吗?

出110入109汤圆

发表于 2012-8-27 09:37:09 | 显示全部楼层
黄花鱼 发表于 2012-8-26 22:44
这个。。。
把P6OUT|=(1

1<<0就等于0x01

出0入0汤圆

 楼主| 发表于 2012-8-27 20:08:53 | 显示全部楼层
我其他地方都没变,就只改了定义了,找不出原因来啊 ...郁闷,.....

出0入0汤圆

发表于 2012-8-27 20:29:02 | 显示全部楼层
楼主没有贴出第一种方法的具体用法。可能只在细节有出入,你这样摘录会隐藏很多细节,别人没法看。比如第二种用法你贴出DCLK=0 DCLK=1这样用 发现运行结果正确了,但漏掉了两个分号。既然正确了,别人可以理解后替你补上。

出0入0汤圆

 楼主| 发表于 2012-8-27 20:51:52 | 显示全部楼层
这是采用位操作的程序:
#define P6                       P6OUT
#define P60                      P6OUT_bit.P6OUT_0
#define P61                      P6OUT_bit.P6OUT_1
#define P62                      P6OUT_bit.P6OUT_2
#define P63                      P6OUT_bit.P6OUT_3
#define P64                      P6OUT_bit.P6OUT_4
#define P65                      P6OUT_bit.P6OUT_5
#define P66                      P6OUT_bit.P6OUT_6
#define P67                      P6OUT_bit.P6OUT_7

#define DCLK         P60   
#define CS       P61
#define DIN      P62
#define BUSY     P63       
#define DOUT     P64                                                                                                                                                                                  
#define Penirq   P65   //触碰触摸屏时,ADS7843Penirq引脚由未触摸时的高电平变为低电平

struct struct1 coordinate;  //定义一个名为Tp_pix的结构变量,用于存放触摸点采样结果
unsigned int  lx,ly;        //根据采集到的参数转换为TFT上的实际坐标值
                           
//Xmin、max和Ymin、Ymax分别是触摸屏横纵坐标的最小/最大值,如果偏差大时,用户可重新标定
#define Xmin           0x0133
#define Xmax           0x0EDA
#define Ymin           0x00D0
#define Ymax           0x0E2F

//================================================================================================
//实现功能:延时
//================================================================================================
void delay_us(unsigned int i)
{
    while(i--);
}

//================================================================================================
//实现功能:    ADS7843启动
//================================================================================================
void start_7843()               
{
           CS=1;
           DIN=0;
           DCLK=0;         
}

//================================================================================================
//    实现功能:  写8位命令到触摸控制IC
//    输入参数:  temp 需要写入的8位控制命令
//================================================================================================
void Write_7843(unsigned char temp)          //SPI写8位命令到触摸控制IC
{
       unsigned char i=0;
       DCLK=0;
       delay_us(1);
       for(i=0;i<8;i++)                         //循环8次写入一字节
       {
              if(temp&0x80)
                    DIN=1;
              else
                    DIN=0;   //判断最高位是否为1,为1则向数据位写1
              DCLK=1;
              delay_us(1);                //送一个脉冲,上升沿有效,将DIN位数据送入到IC
              DCLK=0;
              delay_us(1);                 
              temp<<=1;                        //待写数据左移1位,准备好写下一位数据
       }  
}

//================================================================================================
//    实现功能:  从触摸控制IC读8位数据到控制器
//    返回参数:  temp 需要写入的8位控制命令
//================================================================================================
unsigned int Read_7843()                //SPI 读数据
{
        unsigned char i=0;
        unsigned int temp=0;
        P6DIR&=~(1<<4);                            //设置数据位为输入
        DCLK=1;
        delay_us(1);
        for(i=0;i<12;i++)                   //循环12次读取12位结果
        {
             temp<<=1;                        //temp左移一位,准备读取下一位
             DCLK=0;
             delay_us(1);                //下降沿有效
             DCLK=1;
             delay_us(1);
             if((P6IN&0x10)==0x10)
                    temp++;    //判断控制IC送出的一位数据是否为1,如果为1,赋给temp的最低位
        }
        DCLK=0;
        delay_us(1);
    P6DIR|=(1<<4);                            //设置数据位为输出
    return(temp);                       //返回结果
}   

//================================================================================================
//    实现功能:读取触摸点X轴和Y轴电压值
//    返回参数:pix 读取到的触摸点电压值
//================================================================================================
struct struct1 AD7843()            
{
    struct struct1 pix;
    CS=0;

    Write_7843(0x90);        //送控制字 10010000 即用差分方式读X坐标,详细请见有关资料

    pix.y=Read_7843();

    Write_7843(0xD0);        //送控制字 11010000 即用差分方式读Y坐标 详细请见有关资料
   
    pix.x=Read_7843();

    CS=1;
    return pix;
}

//================================================================================================
//    实现功能:软件滤波,滤掉波动过大的采样点
//    返回参数:flag 采集数据是否有效标志,flag=1;则数据有效
//================================================================================================
unsigned char pix_filter(struct struct1 pix1,struct struct1 pix2)
{
    unsigned char flag=0;
    int x=pix1.x>pix2.x?pix1.x-pix2.x:pix2.x-pix1.x;  //X轴两次采样绝对值
    int y=pix1.y>pix2.y?pix1.y-pix2.y:pix2.y-pix1.y;  //Y轴两次采样绝对值
    if(x<15&&y<15)                                      //软件滤波,2次取样的值相差太大的视为噪声
    {
        flag=1;
        coordinate.x=(pix1.x+pix2.x)/2;               //求两次采样平均值
        coordinate.y=(pix1.y+pix2.y)/2;
    }   
    return flag;
}



//================================================================================================
//    实现功能:读取采集结果,两次取均值
//================================================================================================
unsigned char Getpix() //取采样值,此处使用软件滤波,2次取样的值相差太大的视为噪声
{
    unsigned char flag=0;
    struct struct1 pix1;
    struct struct1 pix2;
    P6DIR&=~(1<<5);                       //设置笔中断位为输入
    if ((P6IN&0x20)==0x00)
        {
               pix1=AD7843();
               pix2=AD7843();

            if(pix_filter(pix1,pix2)==1) //得到当前TP的取样值,此处使用软件滤波,2次取样的值相差太大的视为噪声
                {
                       if((coordinate.x>Xmin)&&(coordinate.y>Ymin))
                       {      
                       //横向X 纵向Y X:0--240  Y;0--320
                              lx=240.0*(coordinate.x-Xmin)/(Xmax-Xmin);   //坐标转换,即根据采样值计算实际坐标值
                              ly=320.0*(coordinate.y-Ymin)/(Ymax-Ymin);   //Xmin、max和Ymin、Ymax分别是触摸屏横纵坐标的最小/最大值
                              flag=1;
                       }
                }                 
        }

    return flag;     
}








这个是原来运行结果不对的程序:


#define  DCLK_H     P6OUT|=(1<<0)
#define  DCLK_L     P6OUT&=~(1<<0)
#define  CS_H       P6OUT|=(1<<1)
#define  CS_L       P6OUT&=~(1<<1)
#define  DIN_L      P6OUT|=(1<<2)
#define  DIN_H      P6OUT&=~(1<<2)
#define  BUSY_OK       P6IN&0x08    //为0表示不繁忙可读数据
#define  DOUT       P6IN&0x10     //触摸屏的数据输出

#define  Penirq     P6IN&0x20    //触碰触摸屏时,ADS7843Penirq引脚由未触摸时的高电平变为低电平

struct struct1 coordinate;  //定义一个名为Tp_pix的结构变量,用于存放触摸点采样结果
unsigned int  lx,ly;        //根据采集到的参数转换为TFT上的实际坐标值
                           
//Xmin、max和Ymin、Ymax分别是触摸屏横纵坐标的最小/最大值,如果偏差大时,用户可重新标定
#define Xmin           0x0133
#define Xmax           0x0EDA
#define Ymin           0x00D0
#define Ymax           0x0E2F

//================================================================================================
//实现功能:延时
//================================================================================================
void delay_us(unsigned int i)
{
    while(i--);
}

//================================================================================================
//实现功能:    ADS7843启动
//================================================================================================
void start_7843()               
{
           CS_H;
           DIN_L;
           DCLK_L;      
}

//================================================================================================
//    实现功能:  写8位命令到触摸控制IC
//    输入参数:  temp 需要写入的8位控制命令
//================================================================================================
void Write_7843(unsigned char temp)          //SPI写8位命令到触摸控制IC
{
       unsigned char i=0;
       DCLK_L;
       delay_us(1);
       for(i=0;i<8;i++)                         //循环8次写入一字节
       {
              if(temp&0x80)
                    DIN_H;
              else
                    DIN_L;   //判断最高位是否为1,为1则向数据位写1
              DCLK_H;
              delay_us(1);                //送一个脉冲,上升沿有效,将DIN位数据送入到IC
              DCLK_L;
              delay_us(1);                 
              temp<<=1;                        //待写数据左移1位,准备好写下一位数据
       }  
}

//================================================================================================
//    实现功能:  从触摸控制IC读8位数据到控制器
//    返回参数:  temp 需要写入的8位控制命令
//================================================================================================
unsigned int Read_7843()                //SPI 读数据
{
        unsigned char i=0;
        unsigned int temp=0;
        P6DIR&=~(1<<4);                            //设置数据位为输入
        DCLK_H;
        delay_us(1);
        for(i=0;i<12;i++)                   //循环12次读取12位结果
        {
             temp<<=1;                        //temp左移一位,准备读取下一位
             DCLK_L;
             delay_us(1);                //下降沿有效
             DCLK_H;
             delay_us(1);
             if((P6IN&0x10)==0x10)
                    temp++;    //判断控制IC送出的一位数据是否为1,如果为1,赋给temp的最低位
        }
        DCLK_L;
        delay_us(1);
    P6DIR|=(1<<4);                            //设置数据位为输出
    return(temp);                       //返回结果
}   

//================================================================================================
//    实现功能:读取触摸点X轴和Y轴电压值
//    返回参数:pix 读取到的触摸点电压值
//================================================================================================
struct struct1 AD7843()            
{
    struct struct1 pix;
    CS_L;

    Write_7843(0x90);        //送控制字 10010000 即用差分方式读X坐标,详细请见有关资料

    pix.y=Read_7843();

    Write_7843(0xD0);        //送控制字 11010000 即用差分方式读Y坐标 详细请见有关资料
   
    pix.x=Read_7843();

    CS_H;
    return pix;
}

//================================================================================================
//    实现功能:软件滤波,滤掉波动过大的采样点
//    返回参数:flag 采集数据是否有效标志,flag=1;则数据有效
//================================================================================================
unsigned char pix_filter(struct struct1 pix1,struct struct1 pix2)
{
    unsigned char flag=0;
    int x=pix1.x>pix2.x?pix1.x-pix2.x:pix2.x-pix1.x;  //X轴两次采样绝对值
    int y=pix1.y>pix2.y?pix1.y-pix2.y:pix2.y-pix1.y;  //Y轴两次采样绝对值
    if(x<15&&y<15)                                      //软件滤波,2次取样的值相差太大的视为噪声
    {
        flag=1;
        coordinate.x=(pix1.x+pix2.x)/2;               //求两次采样平均值
        coordinate.y=(pix1.y+pix2.y)/2;
    }   
    return flag;
}



//================================================================================================
//    实现功能:读取采集结果,两次取均值
//================================================================================================
unsigned char Getpix() //取采样值,此处使用软件滤波,2次取样的值相差太大的视为噪声
{
    unsigned char flag=0;
    struct struct1 pix1;
    struct struct1 pix2;
    P6DIR&=~(1<<5);                       //设置笔中断位为输入
    if ((P6IN&0x20)==0x00)
        {
               pix1=AD7843();
               pix2=AD7843();

            if(pix_filter(pix1,pix2)==1) //得到当前TP的取样值,此处使用软件滤波,2次取样的值相差太大的视为噪声
                {
                       if((coordinate.x>Xmin)&&(coordinate.y>Ymin))
                       {      
                       //横向X 纵向Y X:0--240  Y;0--320
                              lx=240.0*(coordinate.x-Xmin)/(Xmax-Xmin);   //坐标转换,即根据采样值计算实际坐标值
                              ly=320.0*(coordinate.y-Ymin)/(Ymax-Ymin);   //Xmin、max和Ymin、Ymax分别是触摸屏横纵坐标的最小/最大值
                              flag=1;
                       }
                }                 
        }

    return flag;     
}



主程序中都是调用Getpix()函数,前者就能读回坐标,后者就是读不出来,而且屏的确按下了,但是不产生笔中断........望指教....

出0入0汤圆

 楼主| 发表于 2012-8-28 19:31:09 | 显示全部楼层
再顶了啊。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-28 16:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表