基于AVR单片机--Atmega16的1602液晶使用
ATmega16驱动LCD1602显示字符

#include <mega16.h>#include <delay.h>#define RS PORTD.4 //RS: 1-data; 0-cmd#define RW PORTD.5 //RW: 1-Read; 0-Write#define EN PORTD.6/****************************************************************************LCD写数据函数*************************/ void LCD_write_data(unsigned char data){EN=0;RS=1;PORTB=data; //送数据EN=1;delay_ms(1);EN=0;}/*************************************************************************LCD写命令函数***************************/ void LCD_write_cmd(unsigned char cmd){EN=0;RS=0;PORTB=cmd; //送命令码EN=1;delay_ms(1);EN=0;}/*************************************************************************LCD输出字符串函数************************/ void LCD_puts(unsigned char addr,unsigned char *str){unsigned char i=0;LCD_write_cmd(addr|0x80); //设置显示起始位置delay_ms(1);for(i=0;str[i]!='\0';i++) //输出字符串{LCD_write_data(str[i]);delay_ms(1);}}/*************************************************************** *******************LCD初始化*******************************/ void LCD_init(){DDRD.4=1; //设PD4~PD6为输出DDRD.5=1;DDRD.6=1;DDRB=0xff; //PB各口设为输出LCD_write_cmd(0x38); //2行,5*7点阵/每字符delay_ms(1);LCD_write_cmd(0x01); //LCD清屏delay_ms(1);LCD_write_cmd(0x06); //字符输入模式;地址增量,显示屏不动,字符后移delay_ms(1);LCD_write_cmd(0x0c); //显示开,光标不显示不闪烁delay_ms(1);//RW=0;}/******************主函数*********************************/void main (){LCD_init();LCD_puts(0x02,"I LOVE DSP"); //LCD从0行3列开始显示“I LOVE SYSU"LCD_puts(0x41,"Sun Yat-sen"); //LCD从1行1列开始显示“Sun Yat-sen" }。
使用AVR单片机ATmega 32驱动HF1601A LCD液晶屏

使用AVR单片机ATmega 32驱动HF1601A LCD液晶屏HF1601A液晶显示模块,使用的是S6A0069显示芯片。
各个引脚简单说明一下://HF1601A液晶显示屏在AVR单片机的驱动程序采用4位并口方式测试成功//name: HF1601A LCD驱动程序1//mcu: ATmega32//software: winavr//time: 2012.9.22//author: jida//--------------------------------------------// RS ---- PB3 LCD寄存器数据/命令(1/0)// RW ---- PB0 LCD读/写(1/0)// EN ---- PB2 LCD使能读/写(1/1->0)// PA ---- DB LCD数据总线//--------------------------------------------#include <avr/io.h>#include <util/delay.h>#include <avr/interrupt.h>//--------------------------------------------#define FREQ 12 //晶振12MHz//--------------------------------------------#define RS PB3 //LCD寄存器数据/命令(1/0)#define RW PB0 //LCD读/写(1/0)#define EN PB2 //LCD使能读/写(1/1->0)#define DB4 PA4#define DB5 PA5#define DB6 PA6#define DB7 PA7//--------------------------------------------#define LCD_RS_DDR DDRB#define LCD_RW_DDR DDRB#define LCD_EN_DDR DDRB#define LCD_RS_PORT PORTB#define LCD_RW_PORT PORTB#define LCD_EN_PORT PORTB#define LCD_DATA_DDR DDRA#define LCD_DATA_PORT PORTA#define LCD_RS (1<<RS) //PB3 out#define LCD_RW (1<<RW) //PB0 out#define LCD_EN (1<<EN) //PB2 out#define LCD_DATA_4 0XF0 //PA4~7 out//--------------------------------------------void LCD_init (void);void LCD_write_cmd (unsigned char cmd);void LCD_write_dat (unsigned char dat);void LCD_set_xy_1601 (unsigned char x, unsigned char y);void LCD_write_str_1601 (unsigned char X,unsigned char Y,char *s);void LCD_set_xy_1602 (unsigned char x, unsigned char y);void LCD_write_str_1602 (unsigned char X,unsigned char Y,unsigned char *s); void delay_ms (unsigned int t);//--------------------------------------------void port_init(void){LCD_DATA_DDR |= LCD_DATA_4; //设置数据为输出(4位并口)LCD_RS_DDR |= LCD_RS; //设置RS端口为输出LCD_RS_PORT |= LCD_RS; //置位RSLCD_RW_DDR |= LCD_RW; //设置RW端口为输出LCD_RW_PORT &= ~LCD_RW; //置零RWLCD_EN_DDR |= LCD_EN; //设置EN端口为输出LCD_EN_PORT |= LCD_EN; //置位EN}//--------------------------------------------void delay_ms(unsigned int t){unsigned int i;for(i = 0; i < t; i++)_delay_loop_2(250 * FREQ);}//--------------------------------------------void LCD_init(void){delay_ms(1000);LCD_write_cmd(0x28); //工作方式为4位数据端口控制显示_delay_loop_2(600 * FREQ); //等待延时1.8mSLCD_write_cmd(0x0c); //显示开_delay_loop_2(24 * FREQ); //等待延时72uSLCD_write_cmd(0x01); //清屏_delay_loop_2(600 * FREQ); //等待延时1.8mS}//--------------------------------------------void LCD_write_str_1601(unsigned char X,unsigned char Y,char *s)//写数据{unsigned char num=0;LCD_set_xy_1601( X, Y ); // 写地址while (*s) // 写显示字符{LCD_write_dat(* s++);num++;if (num ==8) // 第8个字符LCD_set_xy_1601( 0, Y+1 );}}//--------------------------------------------void LCD_set_xy_1601( unsigned char x, unsigned char y ) // 写地址函数{if (y == 0) // 显示左半屏LCD_write_cmd(0x80 + x);else if (y == 1) // 显示右半屏LCD_write_cmd(0xC0 + x);}//--------------------------------------------void LCD_write_str_1602(unsigned char X,unsigned char Y,unsigned char *s) {LCD_set_xy_1602( X, Y ); // 写地址while (*s) // 写显示字符LCD_write_dat(* s++);}//--------------------------------------------void LCD_set_xy_1602( unsigned char x, unsigned char y ) // 写地址函数{if (y == 0) // 显示第一行LCD_write_cmd( 0x80 + x);else if (y == 1) // 显示第二行LCD_write_cmd( 0xC0 + x);}//--------------------------------------------void LCD_write_cmd(unsigned char cmd) // 写命令{LCD_RS_PORT &= ~LCD_RS; // RS=0_delay_loop_2(FREQ);LCD_DATA_PORT &= 0X0F; // 端口清零LCD_DATA_PORT |= (cmd&0XF0); //写高四位_delay_loop_2(FREQ);LCD_EN_PORT |= LCD_EN; //EN=1_delay_loop_2(FREQ);LCD_EN_PORT&=~LCD_EN; //EN=0LCD_DATA_PORT &= 0X0F; //端口清零LCD_DATA_PORT |= (cmd<<4); //写低四位_delay_loop_2(FREQ);LCD_EN_PORT |= LCD_EN; //EN=1_delay_loop_2(FREQ);LCD_EN_PORT&=~LCD_EN; //EN=0if(cmd != 0x01)_delay_loop_2(24 * FREQ); //等待延时72uSelse_delay_loop_2(600 * FREQ); //等待延时1.8mS}//--------------------------------------------void LCD_write_dat(unsigned char dat) // 写字符{LCD_RS_PORT|=LCD_RS; //RS=1_delay_loop_2(FREQ);LCD_DATA_PORT &= 0X0F; //端口清零LCD_DATA_PORT |= (dat&0XF0); //写高四位_delay_loop_2(FREQ);LCD_EN_PORT|=LCD_EN; //EN=1_delay_loop_2(FREQ);LCD_EN_PORT&=~LCD_EN; //EN=0LCD_DATA_PORT &= 0X0F; //端口清零LCD_DATA_PORT |= (dat<<4); //写低四位_delay_loop_2(FREQ);LCD_EN_PORT|=LCD_EN; //EN=1_delay_loop_2(FREQ);LCD_EN_PORT&=~LCD_EN; //EN=0_delay_loop_2(24 * FREQ); //等待延时72uS}//--------------------------------------------int main(void){port_init();LCD_init(); //初始化for(;;) //for循环{//以下可测试16x1的液晶屏-- 已测试成功LCD_write_str_1601(0,0,"Hello World! "); //写数据delay_ms(1000);LCD_write_cmd(0x01); //清屏LCD_write_str_1601(0,1,"Thanks! ");delay_ms(1000);LCD_write_cmd(0x01); //清屏}return 0;}//--------------------------------------------。
基于AVR atmega_16交直流电压表的设计

基于AVR atmega_16交直流电压表的设计本设计是基于ATmega16单片机开发平台和自动控制原理的基础上实现的一种数字电压表系统。
该系统采用ATmega16单片机作为控制核心,以MAX187为数据采样系统,实现被测电压的数据采样;使用系列比较器检测输入电压的范围,并通过继电器阵列实现了输入量程的自动转换;使用HS1602A LCD液晶显示器显示被测电压。
设计所需的全部资源ATmega16L,MAX187,LM324,OP07,继电器,电阻,导线,电容,三极管9013一、课程设计目的实现自动切换量程的数字电压表。
二、用途及功能方法分析根据待测电压的不同,自动切换量程并检测电压的大小。
目前实现电压数字化测量的方法仍然模-数(A/D)转换的方法,而数字电压表种类繁多,型号新异,目前国际仍未有统一的分类方法。
而常用的分类方法有如下几种:1.按用途来分:有直流数字电压表,交、直流数字电压表,交直流万用表等。
2.按显示位数来分:有4位,5位,6位,7位,8位等。
3.按测量速度来分:有低准确度,中准确度,高准确度等。
4.按测量速度来分:有低速,中速,高速,超高速等。
但在日常生活中,数字电压表一般是按照原理不同进行分类的,目前大致分为以下几类:比较式,电压——时间变换式,积分式等。
数字电压表有多种的设计方法,方案是多种多样的,由于大规模集成电路数字芯片的高速发展,各种数字芯片品种多样,导致对模拟数据的采集部分的不一致性,进而又使对数据的处理及显示的方式的多样性。
又由于在现实的工作生活中,电压表的测量测程范围是比较大的,所以必须要对输入电压作分压处理,而各个数据处理芯片的处理电压范围不同,则各种方案的分段也不同。
由此结合设计要求选择由单片机系统及数字芯片构建。
这种方案是利用单片机系统与与其模数转换功能、显示模块等的结合构建数字电压表。
由于单片机的发展已经成熟,利用单片机系统的软硬件结合,可以组装出许多的应用电路来。
实现ATmega16单片机AD键盘与PC机的串口通信并用LCD1602显示程序

编程软件CodeVisionAV
实现功能:单片机与PC机(电脑)之间的串口通信。具体就是单片机最小系统上的AD键盘按键按下后发送键值到串口助手上显示,串口助手发送一串字符到最小系统上的lcd1602显示。
(程序或有冗余)
#include <mega16.h>
#include <delay.h>
data=rx_buffer[rx_rd_index]; //读取缓冲队列中的数据
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli") //关中断
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
delay_us(10);
ADCSRA|=0x40;
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
// USART Receiver buffer:接收器缓冲
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
基于AVR单片机--Atmega16的1602液晶使用

基于AVR单片机--Atmega16的1602液晶使用基于AVR单片机--Atmega16的1602液晶使用本程序使用AVR单片机Atmega16控制1602液晶,并在液晶上显示字符#include#include#include"1602.h"uchar L[]="qq I Miss You";void display()//显示函数{write_com(0x80);show_string(L);//显示字符串}void init()//初始化函数{DDRC=0xff;//全部设置为输出DDRA|=(1<<7)|(1<<6);//设置PA口的第6位(1602的rs控制脚)和第7位(1602的en控制脚)为输出init_1602();//1602液晶初始化}int main(){init();display();while(1);}//1602液晶显示头文件#define uint unsigned int#define uchar unsigned char//PA口的第6位(1602的rs控制脚)和第7位(1602的en控制脚)#define lcdrs0 PORTA &= ~(1 << 6)//第6位输出低电平#define lcdrs1 PORTA |= (1 << 6)//第6位输出高电平#define lcden0 PORTA &= ~(1 << 7)//第7位输出低电平#define lcden1 PORTA |= (1 << 7)//第7位输出高电平void write_com(uchar com)//写命令函数{lcdrs0;PORTC=com;_delay_ms(5);lcden1;_delay_ms(5);lcden0;}void write_date(uchar date)//写数据函数{lcdrs1;PORTC=date;_delay_ms(5);lcden1;_delay_ms(5);lcden0;}void init_1602()//1602液晶初始化函数{lcden0;write_com(0x38);//设置1602显示模式为5*7点阵_delay_ms(5);write_com(0x01);//清屏_delay_ms(5);write_com(0x0c);//开显示,不显示光标,光标不闪烁_delay_ms(5);write_com(0x06);//设置当读或写一个字符后,地址指针加一,且光标加一 _delay_ms(5);//write_com(0x80);//设置写数据起始地址}void show_string(uchar *string)//显示字符串函数{while(*string){write_date(*string++);}}。
AVR单片机ATMEGA161602液晶驱动程序及心得

AVR单片机ATMEGA16 1602液晶驱动程序及心得首先,祝福各位同仁,光棍节快乐!今天,给我最好的节日礼物就是,我自己研发的AVR微控制器芯片开发板,1602液晶屏实验成功!我很欣慰.写了一整天的程序,反复实验,最终在凌晨0点.终于成功了.在此过程中,最大的问题莫过于那个所谓配套的1602液晶屏数据手册!这个手册简直是误人子弟,里面资料写的很含糊.并且有错误,而导致我反复试验失败,最终,我使用了通用的1602液晶屏数据手册,才得以成功.我自制的AVR开发板尺寸和我买的51开发板差不多大小,ATmega16最小系统,8位数码管,蓝光流水灯,isp编程接口.过载保护保险丝,两个74hc573锁存器.1602液晶屏都已焊接完成,万用板是12X18cm的单孔玻纤板(质量不太好,便宜没好货).现在我才发现不够用,模块数量相同的两块实验板,手工焊接的一定要比机器印刷的大2~3倍才行.....没办法,我只能用5X7cm的万用板做小模块,ADC模块,DS1302时钟模块,激光二极管模块等等,然后用杜邦线把它们和AVR核心板链接起来,目前计划是这样的,往往计划很丰满,实际很骨感,伤脑筋啊,,,此次,首次接触了12864大液晶,能显示中文,和超声波测距传感器,这得好好研究一下,我一直想要了解一下2.4g无线传输模块,和陀螺仪传感器,还有GPS模块,不过那些还早,把AVRATMEGA16学的差不多了,再了解,也不迟. /*Program name: AVR ATMEGA16 1602驱动程序初次实验通过时间: 2013-11-11 00:04:01 ^_^ ;注意:在bysy()函数中严重出错!下次注意!while((PINA&0x80)==0x80); 此语句检测到PA7为零时终止循环;表明空闲状态心得:AVR单片机的IO口位操作比较复杂,由三个寄存器控制IO口的输出与输入;DDRn(输出/输入控制) 寄存器;PORTn(输出时控制数据,输入时控制内部上拉电阻)寄存器;PINn(用于读取IO口数据)寄存器;最终校验通过时间: 2013年11月12日15:12:28*/#include ;#include ;#define uint8 unsigned char#define uint16 unsigned int//========IO口位操作========================================void rs(uint8 h)//数据/指令选择操作;{if(h)PORTB|=1<<3; //置一;elsePORTB&=~(1<<3); //清零; }void rw(uint8 h)//读/写选择操作;{if(h==0){PORTB&=~(1<<4); //清零;}else{DDRA=0X00;PORTA=0XFF;PORTB|=1<<4; //置一;}}void e(uint8 h)//传输使能位;{if(h){PORTB|=1<<5;//置一;}elsePORTB&=~(1<<5);//清零;}//=============================================== =========void ddra(uint8 h)//PA口输入输出函数;{if(h){DDRA=0XFF;//输出模式;PORTA=0xff;}else{DDRA=0X00; PORTA=0XFF; } //输入模式并且有上拉; }void busy()//繁忙检测;{ddra(0);//设置PA口为输入,有上拉;do{e(0);//传输使能为0;rs(0);//指令;rw(1);//读;e(1);//e为高电平;}while((PINA&0x80)==0x80);//如果读到数据是01111111,表示空闲状态,跳出循环;e(0);ddra(1);//PA口输出状态;}void delay() //小延时;{uint8 j=0;j=1;}void w_cmd(uint8 cmd){busy();//繁忙检测通过时,PA口为输出状态,默认输出0xff; PORTA=cmd; //向PA口装载数据;rs(0);//指令;rw(0);//写入;e(1);//传输使能脉冲高;delay();//延时;e(0);//传输使能脉冲低;}void w_dat(uint8 dat){busy();//繁忙检测通过时,PA口为输出状态,默认输出0xff; PORTA=dat; //向PA口装载数据;rs(1);//数据;rw(0);//写入;e(1);//传输使能脉冲高;delay();//延时;e(0);//传输使能脉冲低;}void init_1602(){w_cmd(0x3c); //写入显示设置:8位数据,两行,5x10显示;w_cmd(0x0c); //整屏显示,光标不闪,字符不闪; w_cmd(0x06); //写入一个数据时地址自动加一.整屏不移动;w_cmd(0x01); //写入'清屏'指令;}void display(uint8 addr ,uint8 dat )//可在任意位置显示字符,{//addr地址,dat数据;w_cmd(addr);w_dat(dat);}void main(void)//====主函数================={uint8 i=0, j=0x80,ak[]="I'am ironman!"; //要显示的字符串"我是钢铁侠!"uint8 sj[]="2013-11-11 ^_^"; //今天的日期;uint16 s=0;//16位的变量;DDRB=0XFF;//PB口输出状态;PORTB=0X03; //PB0=1;PB1=1;DDRA=0XFF;//PA口输出状态;PORTA=0X00;//8个数码管共阴极为'0'.八位阳极为'0'; PORTB=0X00;//锁存数据;init_1602();//液晶屏初始化;w_cmd(0x81); //初始化完成以后先发送要写入的数据的显示位置.//0x81是第一行,第1位. 0x80是第0位;while(ak[i]!='\0') //将ak[]数组内的所有数据发送; {w_dat(ak[i++]);//每发送一个字节数据,数据的存储地址自动加一; for(s=0;s<50000;s++); //延时一下,字符会有一个,一个显示的效果;}w_cmd(0xc1);//发送第二排的数据地址,接下来字符会在第二排第1位开始显示;i=0;while(sj[i]!='\0')//将sj[]数组内的数据全部发完;{w_dat(sj[i++]);for(s=0;s<25000;s++);//效果延时;}while(1);//死亡循环; }。
avrMEGA16单片机控制DS1302时钟芯片1602液晶显示

avr MEGA16单片机控制DS1302时钟芯片1602液晶显示/*程序名(program name) : 时钟芯片控制程序;概述 : 基于本程序的开发板是本人自主研发的YF-A1 AVR MEGA16单片机芯片开发板,信号辅助硬件工具有一部8通道的24兆赫兹的逻辑分析仪和一部万用表,通俗的讲,此程序就是开发板的操作系统,以MEGA16A为中央控制芯片,来控制DS1302时钟芯片,使其时间数据显示在1602液晶屏上;我用业余时间大概写了三天左右....得以完善,这次我写的比较顺利,错误只有两点,一是将写好的程序下载入芯片后,时间不走,错误在于写错了时序,用逻辑分析仪捕捉信号后,修正,KO! 二是时间可以走,但是跑秒区并非从0走到59,问题在于显示时,直接显示BCD码,并未将BCD码转换为十进制数,修正后OK!此程序还用到了定时器模块,定时每100毫秒读一次时间数据,并显示在液晶屏上;心得: 此次又突破了以往的程序量,这是我写的目前最大的一个程序,由于AVR芯片IO口控制比较复杂,所以程序语句比较多,但是此程序还有精简的空间,IO口的初始化很重要!finish time: 2014年3月7日13:16:14 作者: 肖邦;QQ: 14-545-07665 ;TEL: SORRY 保密;地址: 新疆昌吉回族自治州昌吉市;梦想: 将托尼*斯塔克成为现实;*/#include ;#include ;//此头文件用于中断服务,本程序中可以省略; typedef unsigned char uint8;typedef unsigned int uint16;void init_io(void) //====初始化所有io口;{DDRA=0XFF;PORTA=0XFF;DDRB=0XFF;PORTB=0X00;DDRC=0XFF;PORTC=0X00;DDRD=0XFF;PORTD=0X00;}//================IO口的位操作================== void rs(uint8 a) //指令/数据位/ ===========DS1302时钟位;{if(a) { PORTB|=1;>;=1;}}uint8 ds_read(void) // DS1302读取函数;{uint8 j=0,temp=0;DDRB&=~(1;>;=1;if((PINB&0X10)==0X10)//如果PB4口读到1;{temp|=0x80;//装载数据;}rs(1); //下降沿有效;delay2(); //时钟脉宽延时;rs(0);}DDRB|=1<<4; // rw引脚输出状态;PORTB|=1<<4; //rw引脚输出1;rs(0);rw(0);return (temp);}void w_1302(uint8 addr,uint8 dat) //写一个地址,写一个数据;{ds_write(addr);ds_write(dat);}void ds_wp(uint8 j) //j==1:不能够写入数据,j==0:可以写入数据;{reset_1302(); //初始化时钟,数据,片选线;ds(1);w_1302(0x8e,j?0x80:0); //三目运算;ds(0);void set_time(uint8 * dat) //设置时间;{uint8 r=0 ,t=0, ad=0x80;for(r=0;r<7;r++) //BCD码的转换.{t=dat[r]%10;dat[r]=dat[r]/10;dat[r]=(dat[r]*16)+t;}ds_wp(0);//可以写入数据;for(r=0;r<7;r++){reset_1302(); //初始化1302;ds(1); //传输使能开;ds_write(ad); //写入"写"操作地址; ds_write(dat[r]);//写入时间数据;ds(0);ad+=2;//地址加2;}ds_wp(1);//禁止写入数据;void read_time(uint8 * dat){uint8 j=0,addr=0x81 ;for(j=0;j<7;j++){reset_1302();ds(1); //传输使能开;ds_write(addr); //发送读取地址; dat[j]=ds_read(); //接收读到的数据; ds(0); //传输使能关;addr+=2; //读取地址加2;}}void timer0(void) //定时器模块函数; {TCNT0=22; //每5毫秒溢出一次;TCCR0=0X04; //256分频;}int main(void){uint8 j=0;uint8 sj[]={20,23,13,7,3,5,14}; init_io(); //初始化所有io口;init_lcd(); //初始化1602液晶屏; play(0x82,'2');delay1(3,2);play(0x83,'0');delay1(3,2);play(0x86,'-');delay1(3,2);play(0x89,'-');delay1(3,2);play(0x8d,'(');delay1(3,2);play(0x8f,')');delay1(3,2);play(0xc4,':');delay1(3,2);play(0xc7,':');delay1(3,2);buzz(); //蜂鸣器叫;delay1(3,2);set_time(sj); //设置时间;timer0(); //运行定时器;while(1){if(TIFR&0X01) //定时器溢出了;{j++;TCNT0=22;TIFR|=0X01;//溢出位置一清零;}if(j==20){j=0;read_time(sj);play(0xc9,sj[0]%16+'0'); //秒个位; play(0xc8,sj[0]/16+'0'); //秒十位;play(0xc6,sj[1]%16+'0'); //分个位; play(0xc5,sj[1]/16+'0'); //分十位; play(0xc3,sj[2]%16+'0'); //时个位; play(0xc2,sj[2]/16+'0'); //时十位;play(0x8b,sj[3]%16+'0'); //号个位; play(0x8a,sj[3]/16+'0'); //号十位; play(0x88,sj[4]%16+'0'); //月个位; play(0x87,sj[4]/16+'0'); //月十位;play(0x8e,sj[5]+'0'); //星期;play(0x85,sj[6]%16+'0'); //秒个位; play(0x84,sj[6]/16+'0'); //秒十位;}}}。
AVR事无巨细系列六,LCD1602(1)

事无巨细,LCD1602前面总算走完了对AVR MEGA16这块单片机的一些基本的应用方式了,这时候大家对AVR 的一些内部资源比如定时器,ADC ,最主要的IO 口的使用方式应该有了一个虽比较粗浅但是却比较形象的认识了。
这节我们来看使用单片机的另外一大主题,就是用单片机来实现芯片控制。
在前面的数码管显示一文中,就已经涉及到了用单片机来控制芯片为我们工作,CEPARK AVR 开发板,为了达到增强驱动能力和节省IO 口的作用,运用了移位寄存器74HC595来驱动两个四位八段数码管,是一个十分有创意的设计。
但是前面的内容重心还是集中于对AVR 的IO 口的控制,所以,我们从这节开始要正式逐渐深入的接触各种芯片了。
先做个引子。
单片机是一种微控制器,本身内部集成了数种资源比如CPU 、内存、内部和外部总线系统,目前大部分还会具有外存。
他的主要任务是利用各种资源实现电平控制,可以以此控制与它相连的下级系统,广泛用于工业自动控制领域。
我们就从这句话出发,首先单片机用来做控制用的,而且是利用的是本身的内部资源。
但是,它的功能再强大,资源再丰富也总有一个上限,总有枯竭的一天。
所以我们常常利用单片机外接芯片来弥补或者增强单片机的功能来完成我们所需功能的电路。
比如程序存储器不足,可以外接外部存储器,比如单片机内部中断级不足,可以外接中断控制器等等。
大家可以从这个角度来理解芯片控制的意义罢。
今天我们用AVR 单片机来实现对LCD1602液晶显示芯片的控制。
首先从这个名字讲起,LCD :英文全称为Liquid Crystal Display ,即为液态晶体显示,也就是我们常说的液晶显示了。
(平时老说LCDLCD ,可能大家也都不怎么注意过这个全称吧,呵呵,当增加词汇量了)1602则是表示这个液晶一共能显示2行数据,每一行显示16个字符。
这个就是LCD1602的全部来由。
液晶显示的使用有多广泛我就不多说了,LCD1602好像10元左右就可以拿到了的,不算贵。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于AVR单片机--Atmega16的1602液晶使用
本程序使用AVR单片机Atmega16控制1602液晶,并在液晶上显示字符
#include<avr/io.h>
#include<util/delay.h>
#include"1602.h"
uchar L[]="qq I Miss You";
void display()//显示函数
{
write_com(0x80);
show_string(L);//显示字符串
}
void init()//初始化函数
{
DDRC=0xff;//全部设置为输出
DDRA|=(1<<7)|(1<<6);//设置PA口的第6位(1602的rs控制脚)和第7位(1602的en控制脚)为输出
init_1602();//1602液晶初始化
}
int main()
{
init();
display();
while(1);
}
//1602液晶显示头文件
#define uint unsigned int
#define uchar unsigned char
//PA口的第6位(1602的rs控制脚)和第7位(1602的en控制脚)
#define lcdrs0 PORTA &= ~(1 << 6)//第6位输出低电平
#define lcdrs1 PORTA |= (1 << 6)//第6位输出高电平
#define lcden0 PORTA &= ~(1 << 7)//第7位输出低电平
#define lcden1 PORTA |= (1 << 7)//第7位输出高电平
void write_com(uchar com)//写命令函数
{
lcdrs0;
PORTC=com;
_delay_ms(5);
lcden1;
_delay_ms(5);
lcden0;
}
void write_date(uchar date)//写数据函数
{
lcdrs1;
PORTC=date;
_delay_ms(5);
lcden1;
_delay_ms(5);
lcden0;
}
void init_1602()//1602液晶初始化函数
{
lcden0;
write_com(0x38);//设置1602显示模式为5*7点阵
_delay_ms(5);
write_com(0x01);//清屏
_delay_ms(5);
write_com(0x0c);//开显示,不显示光标,光标不闪烁
_delay_ms(5);
write_com(0x06);//设置当读或写一个字符后,地址指针加一,且光标加一 _delay_ms(5);
//write_com(0x80);//设置写数据起始地址
}
void show_string(uchar *string)//显示字符串函数
{
while(*string)
{
write_date(*string++);
}
}。