打印
[AVR单片机]

AVR红外遥控1602显示地址与数据的问题

[复制链接]
817|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yutanzang|  楼主 | 2015-3-17 19:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1602显示错误,只显示地址,数据没有反应,一直是0x0000,求大神解决
#include<avr/io.h>
#include<avr/interrupt.h>
#include<math.h>
#include "util/delay.h"

#define uint unsigned int
#define uchar unsigned char
#define RS PA4           //数据/命令控制端 0命令,1数据
#define RW PA5           //读/写选择控制端 0写,1读
#define E PA6

volatile uchar hwtimer;
char startflag=0,recflag=0;
uint timer[33],bitnum;
uint lastdat[4];
uchar count,q,b,s,g;
uint dizhi,shuju;

void Check_Busy();
void delay_ms(uint z) //延时函数
{
   uint x,y;
   for(x=z;x>0;x--)
    for(y=1600;y>0;y--)
         {
            asm("nop");
                asm("nop");
                asm("nop");
                asm("nop");
                asm("nop");
         }
}

void int0_init(void)  //外部中断初始化
{
  DDRD&=~_BV(PD2);  //此处必须把int0引脚设置为输入带上拉
  PORTD|=_BV(PD2);
  MCUCR|=_BV(ISC01);
  GICR|=_BV(INT0);
  sei();
}

void timer0_init(void) //内部定时器0初始化
{
  TCCR0|=_BV(CS01);
  TCNT0=0;
  sei();
}

void fltimer(void) //把33位数据分离成4个字节并且去掉引导码
{
   int j,value,k,i;
   
   j=1;
   if(recflag)
    {
          for(k=0;k<4;k++)
           {
                  for(i=0;i<8;i++)
                   {  
                          value>>=1;
                          if(timer[j]>=8&&timer[j]<=9)  //判断接收到的代码是“1”还是“0”
                           {
                             value=value|0x80;
                           }
                           if(timer[j]<=5&&timer[j]>=4)
                           j++;
                           value=value;
                   }
                   lastdat[k]=value;
                  value=0;
            }
        }
}
void Write_Com(unsigned char LCD_Com)
{
        Check_Busy();
       
        PORTA &= ~(1 << RS);     //RS=0,写命令
        PORTA &= ~(1 << RW);     //RW=0,写指令
        PORTA |= (1 << E);       //E=1,写操作
        _delay_ms(5);
        PORTB = LCD_Com;         //指令送数据端口
        PORTA &= ~(1 << E);     //E=0,停止写操作
        _delay_ms(5);
       
}

void Write_Data(unsigned char LCD_Data)
{
        Check_Busy();

        PORTA |= (1 << RS);      //RS=1,写数据
        PORTA &= ~(1 << RW);    //RW=0,写指令
        PORTA |= (1 << E);      //E=1,写操作
        _delay_ms(5);  
        PORTB = LCD_Data;        // 数据送数据端口   
        PORTA &= ~(1 << E);    //E=0,停止写操作
        _delay_ms(5);
       
}
void LCD_Init()
{
        Write_Com(0X01);  //清屏
        _delay_ms(5);
        Write_Com(0X38);  //显示模式设置 16x2显示,5x7点阵,8位数据接口
        _delay_ms(5);
        //Write_Com(0X0f);  //显示开关控制,开显示,光标显示,光标闪烁
        Write_Com(0X0c);  //显示开关控制,开显示,光标不显示,光标不闪烁
        _delay_ms(5);
        Write_Com(0X06);  //光标设置,读或写一个字符后,地址指针加一,光标加一,整屏不移动
        _delay_ms(5);
}
void Check_Busy()
{
           
        DDRB = 0X00;             //PB口置为输入口,准备读取数据
        PORTA &= ~(1 << RS);      //RS=0,读命令
        PORTA |= (1 << RW);    //RW=1,读指令
        PORTA |= (1 << E);      //E=1,使能
       
        while(0X80 & PINB);   //监测忙信号,直到忙信号为0,才能进行读写操作
        PORTA &= ~(1 << E);   //E=0
        DDRB = 0XFF;          //PB口置为输出口,准备向端口发送数据
}
void change(uint z)//把uint型转换成uchar型
{
q=z/4096;
b=z/256%16;
s=z/16%16;
g=z%16;
if(q>9)q=q+7;
if(b>9)b=b+7;
if(s>9)s=s+7;
if(g>9)g=g+7;
}

void display(uint dizhi, uint shuju)
{/*uint Disp_Number;
        for(Disp_Number = 0;Disp_Number < 16;Disp_Number++)
        {
                Write_Data(dizhi);
                _delay_ms(5);
        }
        Write_Com(0X80+0X40);
        for(Disp_Number = 0;Disp_Number < 16;Disp_Number++)
        {
                Write_Data(shuju);
                _delay_ms(5);
        }*/
  Write_Com(0x80);

Write_Data('0');
Write_Data('X');
change(dizhi);
Write_Data(q+48);
Write_Data(b+48);
Write_Data(s+48);
Write_Data(g+48);
Write_Com(0x80+0x40);

Write_Data('0');
Write_Data('X');
change(shuju);
Write_Data(q+48);
Write_Data(b+48);
Write_Data(s+48);
Write_Data(g+48);
}
//
/*void show_num(void)
{
  display(0,lastdat[3]/16);
  display(1,lastdat[3]%16);
  display(2,lastdat[2]/16);
  display(3,lastdat[2]%16);
}*/

int main(void) //主函数
{

  //LCD数据端口设置
        PORTB = 0X00;         //
        DDRB = 0XFF;           //配置端口PB全部为输出口,LCD数据端口
       
        //LCD控制端口设置
        PORTA = 0X00;         //
        DDRA |= (1 << RS) | (1 << RW) | (1 << E);
        LCD_Init();
         int0_init();
  timer0_init();
  while(1)
  {
     fltimer();
         display(lastdat[0], lastdat[3]);
  }
}

SIGNAL(SIG_OVERFLOW0) //8位定时器0,没256us hwtimer自加一次
{
   TCNT0=0;
   hwtimer++;
}

SIGNAL(SIG_INTERRUPT0) //外部中断函数
{
    if(startflag)
         {
           TIMSK|=_BV(TOIE0);
           if(hwtimer>51) //接收到引导码 13.5/0.256=52
            {
                  bitnum=0;
                }
        timer[bitnum]=hwtimer; //采集16位用户码和16位数据码
                hwtimer=0;
                bitnum++;
                if(bitnum==33)
                 {
                   bitnum=0;
                   recflag=1;
                 }

         }
         else  //在没有接收到数据关闭定时器,并且清零hwtimer确保在接收到数据时计数器从零开始计数
        {
           TIMSK&=~_BV(TOIE0);
           startflag=1;
           hwtimer=0;
         }
}

相关帖子

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

本版积分规则

1

主题

1

帖子

0

粉丝