打印
[AVR单片机]

CTLPORTC|= (Dat>>i)&0x01;

[复制链接]
3249|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
自由自在2013|  楼主 | 2013-9-10 15:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位高手帮忙分析下:CTLPORTC|= (Dat>>i)&0x01; 语句有问题吗?为什么我调试着感觉程序没有运行该语句呢?,完整程序如下:
#include "iom64v.h"
#include "LCD.H"
#include "MACROS.H"

//主控单片机型号Atmega64;
//晶振:内部晶振8MHz,程序烧写时选择合适的选项;
//时钟周期: T1=1/fosc=1/(8*10M);

uint cuont;

/*============================================
函数功能:延时函数
入口参数:无
返回参数:无
备    注:延时时间1ms
============================================*/  
void Delay_1ms (uint cuont)                                     //cuont=200,Delay=200ms
{        
        uint j;
        for(;cuont>0;cuont--)
        {
          for(j=8000;j>0;j--)
          {;}
        }
}

/*============================================
函数功能:写ID
入口参数:ID号,模式
返回参数:无
备    注:写完ID后,写CMD,CS不能拉高
============================================*/  
void Write_ID(uchar ID)                       
{
  uchar i ;
  /*
  for(i=0;i<3;i++)
  {
     
            CLR_LCD_WR;                          // WR=0;
         Delay_1ms(5);
     CTLPORTC|=(ID>>i)&0x01;     
     Delay_1ms(5);
     SET_LCD_WR;
     Delay_1ms(5);         
   }
  */
  CLR_LCD_WR;                        //WR=0;
  Delay_1ms(2);
  CTLPORTC|=(ID&0x04)>>2;
  Delay_1ms(2);
  SET_LCD_WR;                        //WR=1;
  Delay_1ms(2);
  
  CLR_LCD_WR;                       //WR=0;
  Delay_1ms(2);
  CTLPORTC|=(ID&0x02)>>1;
  Delay_1ms(2);
  SET_LCD_WR;                                      //WR=1;
  Delay_1ms(5);
  
  CLR_LCD_WR;                             //WR=0;
  Delay_1ms(2);
  CTLPORTC|=ID&0x01;                  
  Delay_1ms(2);
  SET_LCD_WR;                                     //WR=1;
  Delay_1ms(2);
}

/*============================================
函数功能:写命令
入口参数:CMD:指令数据
返回参数:无
备    注:无
============================================*/  
void Write_CMD(uchar CMD)                     
{
  uchar i;
  for(i=0;i<8;i++)
  {
     CLR_LCD_WR;             //WR=0;
           Delay_1ms(2);
     CTLPORTC|=(CMD>>(7-i)) & 0x01;                            
     Delay_1ms(2);
     SET_LCD_WR;                          //WR=1;
     Delay_1ms(2);
  }
  CLR_LCD_WR;                                  //WR=0;
  Delay_1ms(2);
  CLR_LCD_DATA;                                  //DATA=0;
  Delay_1ms(2);
  SET_LCD_WR;                                  //WR=1;
  Delay_1ms(2);
}

/*============================================
函数功能:写地址
入口参数:ADR:起始地址
返回参数:无
备    注:无
============================================*/
void Write_Adr(uchar Adr)                           
{
  uchar i;
  Write_ID(0x05);
  
  CLR_LCD_WR;
  Delay_1ms(2);
  CLR_LCD_DATA;                           //DATA=0;
  Delay_1ms(2);
  SET_LCD_WR;
  Delay_1ms(2);
   
  for(i=0;i<5;i++)
   {
            CLR_LCD_WR;
         Delay_1ms(2);
     CTLPORTC|=(Adr>>(4-i)) & 0x01;   
     Delay_1ms(2);
     SET_LCD_WR;
     Delay_1ms(2);
   }
}
/*============================================
函数功能:写数据
入口参数:Dat:数据
返回参数:无
备    注:无
============================================*/
void Write_Data(uchar Dat)                        
{
   uchar i;
   
   for(i=0;i<4;i++)
   {
            CLR_LCD_WR;
     Delay_1ms(5);          
     CTLPORTC|= (Dat>>i)&0x01;
     Delay_1ms(5);
     SET_LCD_WR;
     Delay_1ms(5);
        }
       
}
/*============================================
函数功能:初始化LCD
入口参数:Dat:数据,CMD:操作码,ADR:RAM地址
返回参数:无
备    注:定义模块:(100 0010 1001) 0X0429;
                    内部RC 振荡方式:(100 0001 1000) 0X0418;
                  开振荡器:(100 0000 0001) 0X0401;
                  开显示器:(100 0000 0011)        0X0403;          
==============================================*/
void Init_LCD(void)
{                        
         SET_LCD_CS1;
         Delay_1ms(1);
         SET_LCD_CS2;
         Delay_1ms(1);
         SET_LCD_DATA;
           Delay_1ms(1);
//====================初始化U1================
           CLR_LCD_CS1;
           Write_ID(0x04);                             //定义模块
           Write_CMD(0x29);
           SET_LCD_CS1;                   
         
         CLR_LCD_CS1;
           Write_ID(0x04);                             //定义内部振荡方式
           Write_CMD(0x18);
           SET_LCD_CS1;  
         
         CLR_LCD_CS1;                                                             
           Write_ID(0x04);
           Write_CMD(0x01);                            //开振荡器
           SET_LCD_CS1;
           Delay_1ms(1);
                  
         CLR_LCD_CS1;
           Write_ID(0x04);
           Write_CMD(0x03);                            //开显示
           SET_LCD_CS1;
           Delay_1ms(1);
         
                        
//====================初始化U2================
     Delay_1ms(1);
         
         CLR_LCD_CS2;
           Write_ID(0x04);                             //定义模块
           Write_CMD(0x29);
           SET_LCD_CS2;
                        
         CLR_LCD_CS2;
           Write_ID(0x04);
           Write_CMD(0x01);                            //开振荡器  
           SET_LCD_CS2;
           Delay_1ms(1);
         
         CLR_LCD_CS1;
           Write_ID(0x04);                             //定义内部振荡方式
           Write_CMD(0x18);
           SET_LCD_CS2;  
          
           CLR_LCD_CS2;
           Write_ID(0x04);
           Write_CMD(0x03);                            //开显示
           SET_LCD_CS2;
           Delay_1ms(1);         
                                     
}

这是个液晶程序,其中每个函数基本都要用到这样的语句,期待各位高手指点!

相关帖子

沙发
netcattle| | 2013-9-10 16:45 | 只看该作者
进汇编看,是不是被优化了,也可以把优化关了,然后看有没有问题。

使用特权

评论回复
板凳
qin552011373| | 2013-9-10 19:15 | 只看该作者
在你所有的变量前加上volatile   然后再进入汇编看看

使用特权

评论回复
地板
奶粉| | 2013-9-10 19:28 | 只看该作者

使用特权

评论回复
5
netcattle| | 2013-9-11 09:34 | 只看该作者
qin552011373 发表于 2013-9-10 19:15
在你所有的变量前加上volatile   然后再进入汇编看看

顺道问一下高人。CTLPORTC是左值,假如这个不加volatile修饰,而给 Dat,i 加volatile 修饰,是不是不能防止编译器的优化?昨天写了一个程序测试了下
void test()
{
  volatile u_char a,i;
u_char b;
for(i = 0;i < 5; i++)
{
b = a;
a ++;
}
}
貌似这样还是会被优化,b的中间值都没显示出来,不知道是不是可以得出在右值的时候,volatile 没有意义?假如测试中的b换成了IO寄存器,怎么去用volatile修饰?

使用特权

评论回复
6
qin552011373| | 2013-9-11 10:27 | 只看该作者
IO寄存器的话在前面已经有了volatile   .H定义的时候已经帮你加上了   最好在有可能被优化的地方加上   防止被优化带来的不可预知的错误

使用特权

评论回复
7
自由自在2013|  楼主 | 2013-9-11 13:05 | 只看该作者
谢谢各位高手指点,我试试看

使用特权

评论回复
8
自由自在2013|  楼主 | 2013-9-11 13:10 | 只看该作者
刚刚试了一下,所有的变量前加上volatile ,还是不行

使用特权

评论回复
9
自由自在2013|  楼主 | 2013-9-11 13:23 | 只看该作者
我用的是ICCavr

使用特权

评论回复
10
netcattle| | 2013-9-11 14:34 | 只看该作者
自由自在2013 发表于 2013-9-11 13:10
刚刚试了一下,所有的变量前加上volatile ,还是不行

那就爱莫能助了,ICCAVR环境没用过,仿真看看吧,FOR循环里观察IO口是否每次循环都变化,
CTLPORTC应该是IO寄存器吧?

使用特权

评论回复
11
自由自在2013|  楼主 | 2013-9-12 08:29 | 只看该作者
CTLPORTC应该是IO寄存器,
#define  CTLPORTC      PORTC
头文件里定义过了。

使用特权

评论回复
12
自由自在2013|  楼主 | 2013-9-12 11:33 | 只看该作者
/*============================================
函数功能:写数据
入口参数:Dat:数据
返回参数:无
备    注:无
============================================*/
void Write_Data(volatile uchar Dat)                        
{
   volatile uchar i,jemp,jemp1;
   
   for(i=0;i<4;i++)
   {           
     SET_LCD_WR;
     Delay_1ms(2);
     jemp=Dat>>i;          
     jemp1=jemp&0x01;
     if(jemp1==0x01)
     {
         SET_LCD_DATA;
     }
    else
    {
        CLR_LCD_DATA;
     }
     Delay_1ms(1);
     CLR_LCD_WR;
     Delay_1ms(2);
   }       
}

CTLPORTC|= (Dat>>i)&0x01,这个语句改成上边的判断、置位形式,测试正常啦

使用特权

评论回复
13
outstanding| | 2013-9-12 11:41 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

83

帖子

3

粉丝