AVR单片机C语言程序设计实验指导书-10页word资料 下载本文

#include #define xtal 8 #define PB0 0 #define PB1 1 #define PB2 2

#define uchar unsigned char #define uint unsigned int

#define SET_BIT(x,y) (x|=(1<

//-------端口电平的宏定义------------ #define LCM_RS_1 SET_BIT(PORTB,PB0) #define LCM_RS_0 CLR_BIT(PORTB,PB0) #define LCM_RW_1 SET_BIT(PORTB,PB1) #define LCM_RW_0 CLR_BIT(PORTB,PB1) #define LCM_EN_1 SET_BIT(PORTB,PB2) #define LCM_EN_0 CLR_BIT(PORTB,PB2) #define DataPort PORTA #define Busy 0x80

//**********函数声明******************** void Delay_1ms(void); void Delay_nms(uint n); void LcdWriteData(uchar W);

void LcdWriteCommand(uchar CMD); void InitLcd(void);

void DisplayLine2(uchar dd);

void DisplayOneChar(uchar x,uchar y,uchar Wdata); void ePutstr(uchar x,uchar y,uchar const *ptr);

/***********显示指定坐标的一串字符子函数************/ void ePutstr(uchar x,uchar y,uchar const *ptr) uchar i,l=0;

while(ptr[l]>31){l++;} for(i=0;i

DisplayOneChar(x++,y,ptr[i]); if(x==16){ x=0;y^=1;

//**********演示第二行移动字符串子函数************ void DisplayLine2(uchar dd) uchar i;

for(i=0;i<16;i++){

DisplayOneChar(i,1,dd++); dd&=0x7f;

if(dd<32)dd=32;

//***********显示光标定位子函数******************

第 5 页

void LocateXY(char posx,char posy) uchar temp=0; temp&=0x7f; temp=posx&0x0f; posy&=0x01;

if(posy)temp|=0x40; temp|=0x80;

LcdWriteCommand(temp);

//**********显示光标定位的一个字符子函数*********** void DisplayOneChar(uchar x,uchar y,uchar Wdata) LocateXY(x,y);

LcdWriteData(Wdata);

//***********LCD初始化子函数****************** void InitLcd(void)

LcdWriteCommand(0x38);//显示模式设置(固定),8位数据接口 Delay_nms(5);

LcdWriteCommand(0x01);//清屏 Delay_nms(5);

LcdWriteCommand(0x0c);//开显示,不显示光标 Delay_nms(5);

//************写命令到LCM子函数************ void LcdWriteCommand(uchar CMD) LCM_RS_0;LCM_RW_0; DataPort=CMD;

LCM_EN_1;Delay_nms(1);LCM_EN_0;

//************写数据到LCM子函数************* void LcdWriteData(uchar dataW) LCM_RS_1;LCM_RW_0; DataPort=dataW;

LCM_EN_1;Delay_nms(1);LCM_EN_0;

//***********1ms延时子函数******************* void Delay_1ms(void) { uint i;

for(i=1;i<(uint)(xtal*143-2);i++)

//=============n*1ms延时子函数================ void Delay_nms(uint n) uint i=0; while(i

第 6 页

实验四 0~5V数字式直流电压表

一、实验目的

1. 掌握A/D转换程序的设计; 2. 掌握数据采集与显示的应用; 3.掌握数据处理的方法;

二、实验内容

1. 参照课本P383页“0~5V数字式直流电压表实验”程序,并编译、仿真,见下图所示。 注意:由于用proteus ISIS仿真时,数码管模型显示的闪烁现象和缓存现象,需要对其进行短延时和清屏,否则,显示将出现乱码现象。可在main()主函数里加入两条语句:

Delay(1); PORTA=0;

(1)修改错误。

比较程序第25行“ADMUX=0XC7”以及程序第71行“x=(5000*(long)i)/1023”所指参考电压不一致,导致输入模拟电压值与数码管显示电压值不一致,有哪几种修改方案。 如把ADMUX=0XC7改为0X07。

(2)调节电位器(POT-LOG),观察数码管显示的电压值与虚拟直流电压表显示的电压是否一致。

2.将编译通过后的程序烧写到单片机里,调节AD电位器,观看开发板上数码管的显示情况。

注意数码管的位选端排列顺序,实验板与课本电路图中数码管排序不同,故需要调整位选端。

3.如果想观察ADC转换后的数字结果,则需将数码管显示改为: PORTA=SEG7[adc_val]; 依次类推。

三、拓展实验

把数码管显示改为LCD1602液晶显示。(可参考P240“0~5V数字电压调整器”lcd部分程序内容)

注意:因使用PA7为输入端口,而PA口为原电路中LCD1602的数据端口,故把数据端口改为PC口,注意要把lcd1602液晶的驱动程序“lcd1602_8bit.c”中的语句“#define DataPort PORTA”改为“#define DataPort PORTC”。Proteus ISIS仿真图如下图。

四、附使用LCD1602显示ADC参考程序

#include

#include \

uchar const title[]={\}; #define uchar unsigned char #define uint unsigned int uint adc_val,dis_val; uchar i,cnt;

/************************************************/

第 7 页

void port_init(void) { PORTA = 0x7F; DDRA = 0x7F; PORTB = 0xFF;

DDRB = 0xFF; PORTC = 0xFF;

DDRC = 0xFF; PORTD = 0xFF; DDRD = 0xFF; }

/************************************************/ void adc_init(void) { ADCSRA = 0xE3;

ADMUX = 0x47; } //***************************

void timer0_init(void) { TCNT0 = 0x83;

TCCR0 = 0x03; TIMSK = 0x01; }

/*********************************************/ void init_devices(void) { port_init(); timer0_init();

adc_init(); SREG =0x80;

} //***************************

#pragma interrupt_handler timer0_ovf_isr:10 void timer0_ovf_isr(void) { TCNT0 = 0x83; cnt++; }

//========================= uint ADC_Convert(void) {uint temp1,temp2; adc_init();

temp1=(uint)ADCL; temp2=(uint)ADCH;

temp2=(temp2<<8)+temp1; return(temp2);

第 8 页