|
本帖最后由 lxren 于 2015-7-6 17:43 编辑
大伙帮忙指点下这个1602的程序,基于IAR for AVR编译器,一直调不过。
有点怀疑读LCD1602忙状态的时候PORTA被编译器优化掉,是否要对PORTA加volatile做说明?要怎么加PORT的volatile???
程序如下:
/***************************************************************************************
****************************************************************************************
* FILE : display.c
* Description :
*
* Copyright (c) 2015 by Manden. All Rights Reserved.
*
* History:
* Version Name Date Description
* 0.1 **** 2015/06/18 Initial Version
****************************************************************************************
****************************************************************************************/
#include <iom16.h>
#include <string.h>
#include "HAL_Type.h"
#include "delay.h"
#include "display.h"
#define DataPort PORTA
#define DataDDR DDRA
#define CTRLPort PORTB
#define CTRLDDR DDRB
#define CLR_RS PORTB_Bit0=0
#define SET_RS PORTB_Bit0=1
#define CLR_RW PORTB_Bit1=0
#define SET_RW PORTB_Bit1=1
#define CLR_EN PORTB_Bit2=0
#define SET_EN PORTB_Bit2=1
void WaitForEnable(void)
{
DataDDR &= 0x00;//数据口置为输入
CLR_RS;
SET_RW;
SET_EN;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
while((DataPort & 0x80)!=0) //检测忙标志
{
CLR_EN;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SET_EN;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
CLR_EN;
DataDDR |=0xff;
}
void write_cmd(unsigned char cmd)//写指令
{
WaitForEnable();
CLR_RS;
CLR_RW;
DataPort = cmd;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SET_EN;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
CLR_EN;
}
void write_data(unsigned char da)//写数据
{
WaitForEnable();
SET_RS;
CLR_RW;
DataPort = da;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SET_EN;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
CLR_EN;
}
void lcd_init()//LCD初始化
{
DataPort &= 0x00; //初始化0
DataDDR |= 0xff; //数据脚设置为输出
CTRLPort &= 0xf8; //控制信号设置为0
CTRLDDR |=0x07; //控制脚设置为输出
write_cmd(0x38); //设置8位格式,2行,5x7
DelayMs(2);
write_cmd(0x08); //显示关闭
DelayMs(2);
write_cmd(0x06); //设定输入方式,增量不移位
DelayMs(2);
write_cmd(0x01); //清显示
DelayMs(2);
write_cmd(0x0c); //整体显示,关光标,不闪烁
DelayMs(2);
}
/********************************************************************
* 名称 : lcd1602_char(uchar row,uchar col,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
lcd1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void lcd1602_char(unsigned char row,unsigned char col,char sign)
{
unsigned char a;
if(row == 1) a = 0x80;
if(row == 2) a = 0xc0;
a = a + col - 1;
write_cmd(a);
write_data(sign);
}
/********************************************************************
* 名称 : lcd1602_string(uchar row,uchar col,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
lcd1602_string(1,5,"ab cd ef");
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void lcd1602_string(unsigned char row,unsigned char col,char *p)
{
unsigned char a;
if(row == 1) a = 0x80;
if(row == 2) a = 0xc0;
a = a + col - 1;
write_cmd(a);
while(1)
{
if(*p == '\0') break;
write_data(*p);
p++;
}
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|