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;
}
} |