做一个基于单片机的汽车超速报警系统,在做液晶显示的时候总是显示不了 无奈之下请教下大家帮帮忙 ,液晶屏有亮度但是没有显示,proteus仿真有结果,一开始以为是辉度问题开始调了好久还是不行。帮忙看看吧 谢谢各位大侠了
/************************************
*********STC89C51**********
**********12MHz晶振********/
#include "reg51.h"
#define uint8 unsigned char
#define uint16 unsigned int
#define uchar unsigned char
#define uint unsigned int
#define TIMER0_HIGHT 0xEC //设置定时器0工作方式1自动装载初值,定时5ms,Fosc=12MHZ
#define TIMER0_LOW 0x78
uint8 keyin = 1; //按键输入
uint16 cnt10ms; //10ms计数器
uint16 Pulsecnt;
uint16 Pulsenum;
uint16 PulseTime; //10ms计数器
uint16 Pulse; //10ms计数器
//--------------------------PWM
#define V_TH1 0xFF
#define V_TL1 0xF6
#define V_TMOD 0x01
unsigned char SETSPEED=150;
unsigned char ZKB1;
unsigned char click=0;
void Init_Extint(void);
void TimerInitProc();
void Init_System(void);
void Display(uint8 chose_dat, uint8 dat);
void ShowDisp(uint8 tPulsenum, uint8 tPulsecnt, uint8 tcnt1s);
void DelayMs(uint8 Ms);
uint8 Pulse_FLAG=0;
#define LCD_Data P0 //LCD的数据口
sbit LCD_BF=LCD_Data^7; //LCD忙信号位
sbit LCD_RS=P2^5;
sbit LCD_RW=P2^6;
sbit LCD_EN=P2^7;
sbit MOTOR_EN=P2^3;//电机
sbit BP_EN=P3^5;//喇叭
sbit red_EN=P1^3;//喇叭
sbit SPEEDADD=P1^0;
sbit SPEEDDEC=P1^1;
sbit K1=P2^0;
sbit K2=P2^1;
sbit K3=P2^2;
#define LCD_GO_HOME 0x02 //AC=0,光标、画面回HOME位
//输入方式设置
#define LCD_AC_AUTO_INCREMENT 0x06 //数据读、写操作后,AC自动增一
#define LCD_AC_AUTO_DECREASE 0x04 //数据读、写操作后,AC自动减一
#define LCD_MOVE_ENABLE 0x05 //数据读、写操作,画面平移
#define LCD_MOVE_DISENABLE 0x04 //数据读、写操作,画面不动
//设置显示、光标及闪烁开、关
#define LCD_DISPLAY_ON 0x0C //显示开
#define LCD_DISPLAY_OFF 0x08 //显示关
#define LCD_CURSOR_ON 0x0A //光标显示
#define LCD_CURSOR_OFF 0x08 //光标不显示
#define LCD_CURSOR_BLINK_ON 0x09 //光标闪烁
#define LCD_CURSOR_BLINK_OFF 0x08 //光标不闪烁
//光标、画面移动,不影响DDRAM
#define LCD_LEFT_MOVE 0x18 //LCD显示左移一位
#define LCD_RIGHT_MOVE 0x1C //LCD显示右移一位
#define LCD_CURSOR_LEFT_MOVE 0x10 //光标左移一位
#define LCD_CURSOR_RIGHT_MOVE 0x14 //光标右移一位
//工作方式设置
#define LCD_DISPLAY_DOUBLE_LINE 0x38 //两行显示
#define LCD_DISPLAY_SINGLE_LINE 0x30 //单行显示
/*定义子程序*/
void LCD_ClrAll(void); //清屏
void Judge_LCD_busy(void); //检测是否忙碌
void LCD_Write(uchar WriteData); //写控制字
void LCD_write_data(uchar LCD_data); //写数据显示
void LCD_cursor(uchar x); //光标起始地址
void LCD_printc(unsigned char lcd_data) ; //输出一个字符
void LCD_prints(unsigned char *lcd_string);//输出字符串
/*LCD1602忙碌判断子程序*/
void Judge_LCD_busy(void) //判断LCD1602是否忙状态
{
while(1)
{
LCD_EN=0;
LCD_RS=0;
LCD_RW=1;
LCD_Data=0xff;
LCD_EN=1; //EN 是 1—0 使能
if(!LCD_BF)break; //LCD_BF=1表示忙碌,需要等待。
}
LCD_EN=0;
}
/******LCD清屏***************/
void LCD_ClrAll(void)
{
Judge_LCD_busy(); //判断是否忙碌
LCD_RS=0;
LCD_RW=0;
LCD_Data=0x01;
LCD_EN=1;
LCD_EN=0;
}
/*******LCD写数据定义各种模式*********/
void LCD_Write(uchar WriteData) //写指令到LCD
{
Judge_LCD_busy();
LCD_RS=0;
LCD_RW=0;
LCD_Data=WriteData; //把WriteData的数据送到数据口
LCD_EN=1;
LCD_EN=0;
}
/********LCD显示数据***********/
void LCD_write_data(uchar LCD_data) //输出一个字节数据到LCD
{
Judge_LCD_busy();
LCD_RS=1;
LCD_RW=0;
LCD_Data=LCD_data;
LCD_EN=1;
LCD_EN=0;
}
/****光标位置的确定***/
void LCD_cursor(uchar x) //LCD光标定位到x处
{
LCD_Write(0x80+x); //第一行地址是0x80
}
/*输出一个字符*/
void LCD_printc(unsigned char lcd_data)
{
LCD_write_data(lcd_data);
}
/*输出字符串*/
void LCD_prints(unsigned char *lcd_string)
{
unsigned char i=0;
while(lcd_string!=0x00)
{
LCD_write_data(lcd_string);
i++;
}
}
/*初始化程序*/
void LCD_initial(void) //初始化LCD
{
LCD_Write(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
LCD_Write(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
LCD_Write(LCD_DISPLAY_DOUBLE_LINE);
LCD_ClrAll();
}
void Value_to_ASCII2(unsigned int value,uchar add)
{
unsigned char temp[] = "00";
temp[0] = value/10 + 0x30;
value = value%10;
temp[1] = value + 0x30;
LCD_cursor(add); //光标起始地址 ,第一行地址是0x00~0x0F,第二行地址是0x40~0x4f
LCD_prints(temp);
}
void Value_to_ASCII(unsigned int value,uchar add)
{
unsigned char temp[] = "000KM/H";
temp[0] = value/100 + 0x30;
value = value%100;
temp[1] = value/10 + 0x30;
value = value%10;
temp[2] = value + 0x30;
LCD_cursor(add); //光标起始地址 ,第一行地址是0x00~0x0F,第二行地址是0x40~0x4f
LCD_prints(temp);
}
void Value_to_ASCII3(unsigned int value,uchar add)
{
unsigned char temp[] = "SET:000KM/H";
temp[4] = value/100 + 0x30;
value = value%100;
temp[5] = value/10 + 0x30;
value = value%10;
temp[6] = value + 0x30;
LCD_cursor(add); //光标起始地址 ,第一行地址是0x00~0x0F,第二行地址是0x40~0x4f
LCD_prints(temp);
}
//--------------------主程序--------------------------------
void main()
{
MOTOR_EN=0;
BP_EN=1;ZKB1=0;
Init_System(); //初始化
LCD_initial();
LCD_cursor(0x00);//写地址
LCD_prints("CAR:");//写内容
Value_to_ASCII(Pulsenum,0X04);
Value_to_ASCII2(ZKB1,0X4c);
Value_to_ASCII3(SETSPEED,0X40);
while(1)
{
//按键处理
if(SPEEDADD==0){//加速
DelayMs(1);
if(SPEEDADD==0){
if(SETSPEED<250)SETSPEED=SETSPEED+10;
Value_to_ASCII3(SETSPEED,0X40);
while(SPEEDADD==0){}
}
}
if(SPEEDDEC==0){//减速
DelayMs(1);
if(SPEEDDEC==0){
if(SETSPEED>10)SETSPEED=SETSPEED-10;
Value_to_ASCII3(SETSPEED,0X40);
while(SPEEDDEC==0){}
}
}
if(K1==0){//设定超速报警速度
DelayMs(1);
if(K1==0){
if(ZKB1)ZKB1--;
Value_to_ASCII2(ZKB1,0X4c);
while(K1==0){}
}
}
if(K2==0){//设定超速报警速度
DelayMs(1);
if(K2==0){
if(ZKB1<50)ZKB1++;
Value_to_ASCII2(ZKB1,0X4c);
while(K2==0){}
}
}
if(K3==0){//设定超速报警速度
DelayMs(1);
if(K3==0){
ZKB1=0;
Value_to_ASCII2(ZKB1,0X4c);
while(K3==0){}
}
}
if(Pulse_FLAG==1){
Pulse_FLAG=0;
Value_to_ASCII(Pulsenum,0X04);
if(Pulsenum>SETSPEED){BP_EN=0;red_EN=0;
}else{BP_EN=1;red_EN=1;}
}
}
}
/*******************************************************************************
* 函 数 名: Exti0_interrupt
* 函数功能: /INT0引脚下降沿进入中断
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void Ext0_interrupt(void) interrupt 0
{
Pulsecnt++; //来一次中断计数器加1
}
/********************************************************************
函数功能:定时器/计数器0中断处理
入口参数:null
返 回:null
备 注:null
********************************************************************/
void Timer0IntProc() interrupt 1
{
TH0 = TIMER0_HIGHT; //设置定时器0高字节初值
TL0 = TIMER0_LOW; //设置定时器0低字节初值
if(++cnt10ms == 200) //1s计时到
{
cnt10ms = 0;
Pulsenum = Pulsecnt; //保存测得脉冲值
Pulsecnt=0;
Pulsenum=(Pulsenum*2)/3; //2个脉冲为1圈
Pulse_FLAG=1;
}
}
/********************************************************************
函数功能:定时器/计数器1中断处理
入口参数:null
返 回:null
备 注:null
********************************************************************/
void Timer1IntProc() interrupt 3
{
TH1 = V_TH1; //设置定时器1高字节初值
TL1 = V_TL1; //设置定时器1低字节初值
++click;
if(click>=50)click=0;
if(click<=ZKB1){
MOTOR_EN=1;
}else{
MOTOR_EN=0;
}
}
/////////////////////////End of Timer0IntProc////////////////////////
void Init_Extint(void)
{
IT0 = 1; //外部中断1设置为下降沿触发
IE0 = 0; //标志位清0
EX0 = 1; //允许外部中断1
}
/********************************************************************
函数功能:定时器/计数器初始化
入口参数:null
返 回:null
备 注:null
********************************************************************/
void TimerInitProc()
{
TMOD &= 0xF0;
TMOD |= 0x11; //设置定时器0,1,方式1:16位定时器
TH0 = TIMER0_HIGHT; //设置定时器0高字节初值
TL0 = TIMER0_LOW; //设置定时器0低字节初值
TR0 = 1; //启动定时器0
ET0 = 1; //开定时器0中断
TH1 = V_TH1; //设置定时器1高字节初值
TL1 = V_TL1; //设置定时器1低字节初值
TR1 = 1; //启动定时器1
ET1 = 1; //开定时器1中断
EA = 1; //开总中断
}
/////////////////////////End of TimerInitProc////////////////////////
void initvar()
{
cnt10ms = 0;
Pulsecnt = 0;
Pulsenum = 0;
}
void Init_System(void)
{
Init_Extint();
TimerInitProc();
initvar();
}
/********************************************************************
函数功能:延时ms
入口参数:MS
返 回:null
备 注:null
********************************************************************/
void DelayMs(uint8 Ms)
{
unsigned char i,j;
do
{
for(i=5;i>0;i--)
for(j=98;j>0;j--);
}while(--Ms);
//Test for 12M
}
///////////////////////////End of DelayMs////////////////////////////
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>