微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ATMEGA16读写24C02 C51程序

ATMEGA16读写24C02 C51程序

时间:08-04 来源:互联网 点击:




完整代码下载地址: http://www.51hei.com/f/2402avr.rar

main函数:/*程序功能:ATMEGA16读写24C02作者:朱波时间:2012年1月30日说明:程序运行后会从0开始自动计数到256(对字节操作的结果)当复位或者断电时24C02保存断电时的数据,当重新启动后计数值会从断电时的值开始计数*/#include iom16v.h>#include macros.h>#include"delay.h"  #include"display.h"#include"24C02.h"#define  uchar unsigned char#define  uint  unsigned intuint num;//定义变量用于读取24C02中的数值,注意必须为uint型void  main(){  LCD_init();twi_init();while(1){num=IIC_Read(0x00);//从器件中读取(0x00是器件地址)num=num+1;//加1num=num%1000;//关键语句,没有此句则不工作*/IIC_Write(num,0x00);//加1后写入器件display();}}延时函数delay.c#include"delay.h"void delay(unsigned int ms){unsigned int i,j;for(i=0;ims;i++){for(j=0;j1141;j++);}}显示函数display.c#include iom16v.h>#include macros.h>#include"display.h"#define  uchar unsigned char#define  uint  unsigned intuchar table1[]="0123456789";uchar table2[]="zhubo-24C02";uchar table3[]="result:";extern uint num;//主函数中的值void write_com(uchar com){PORTD=~BIT(4);PORTD=~BIT(5);PORTB=com;PORTD|=BIT(6);delay(1);PORTD=~BIT(6);}void write_dat(uchar dat){     PORTD|=BIT(4);PORTD=~BIT(5);PORTB=dat;PORTD|=BIT(6);delay(1);PORTD=~BIT(6);}void LCD_init(){ DDRB=0XFF;DDRD|=BIT(4)|BIT(5)|BIT(6);PORTD=~BIT(6);write_com(0X38);delay(5);write_com(0X01);delay(5);write_com(0X0C);delay(5);write_com(0X06);delay(5);}void display(){uint i;write_com(0X80+0);delay(5);for(i=0;i7;i++){write_dat(table3[i]);delay(5);} //这是在1602液晶中显示数值的方法write_com(0X80+8);delay(5);write_dat(table1[num/1000]);delay(5);write_com(0X80+9);delay(5);write_dat(table1[num%1000/100]);delay(5);write_com(0X80+10);delay(5);write_dat(table1[num%100/10]);delay(5);write_com(0X80+11);delay(5);write_dat(table1[num%10]);delay(5);write_com(0X80+0X40);//仿真与实际1602有区别delay(5);for(i=0;i11;i++){write_dat(table2[i]);delay(5);}}24C02.c:#include iom16v.h>#include macros.h>#include"24C02.h"#define  uchar unsigned char#define  uint  unsigned int//主机模式启动状态码#define I2C_START                       0x08   //启动总线#define I2C_RESTART      0x10   //重新启动总线//主机发送模式状态码#define I2C_MT_SLA_ACK   0x18   //SLA+W写地址已发送,收到应答位#define I2C_MT_SLA_NACK  0x20   //SLA+W写地址已发送,收到非应答位#define I2C_MT_DATA_ACK  0x28   //写入数据已发送,收到应答位#define I2C_MT_DATA_NACK 0x30   //写入数据已发送,收到应答位#define I2C_MT_ARB_LOST  0x38   //SLA+W或数据仲裁失败//主机接收模式状态码#define I2C_MR_ARB_LOST  0x38   //SLA+R或NOT ACK的仲裁失败#define I2C_MR_SLA_ACK   0x40   //SLA+R已发送,收到应答位#define I2C_MR_SLA_NACK  0x48   //SLA+R已发送,收到非应答位#define I2C_MR_DATA_ACK  0x50   //接收到数据,应答位已返回#define I2C_MR_DATA_NACK 0x58   //接收到数据,非应答位已返回//从机接收模式状态码#define I2C_SR_SLA_ACK    0x60   //自己的SLA+W已经被接收ACK已返回#define I2C_SR_ARB_LOST_SLA_ACK  0x68   //SLA+R/W作为主机的仲裁失败,自己的SLA+W已经被接收ACK已返回#define I2C_SR_GCALL_ACK   0x70   //接收到广播地址ACK已返回#define I2C_SR_ARB_LOST_GCALL_ACK 0x78   //SLA+R/W作为主机的仲裁失败,接收到广播地址ACK已返回#define I2C_SR_DATA_ACK    0x80   //以前以自己的SLA+W被寻址,数据已经被接收ACK已返回#define I2C_SR_DATA_NACK   0x88   //以前以自己的SLA+W被寻址,数据已经被接收NOT ACK已返回#define I2C_SR_GCALL_DATA_ACK  0x90   //以前以广播方式被寻址,数据已经被接收ACK已返回#define I2C_SR_GCALL_DATA_NACK  0x98   //以前以广播方式被寻址,数据已经被接收NOT ACK已返回#define I2C_SR_STOP     0xA0   //在以从机工作时接收到STOP或重复START//从机发送模式状态码#define I2C_ST_SLA_ACK   0xA8   //自己的SLA+R已经被接收ACK已返回#define I2C_ST_ARB_LOST_SLA_ACK 0xB0   //SLA+R/W作为主机的仲裁失败,自己的SLA+R已经被接收ACK已返回#define I2C_ST_DATA_ACK   0xB8   //TWDR里数据已经被发送接收到ACK#define I2C_ST_DATA_NACK 0xC0   //TWDR里数据已经被发送接收到NOT ACK#define I2C_ST_LAST_DATA  0xC8   //TWDR的一字节数据已经发送(TWAE='0'),接收到ACK//其他状态码#define I2C_NO_INFO   0xF8   //没有相关的状态信息,TWINT='0'#define I2C_BUS_ERROR  0x00   //由于非法的START或STOP引起的总线错误//定义SLA中读写控制位极性#define I2C_READ   1#define I2C_WRITE  0#define RD_DEVICE_ADDR                  0XA1   //写的器件地址#define WD_DEVICE_ADDR                  0XA0   //读的器件地址//常用TWI操作(主模式写和读)#define Start() (TWCR=(1TWINT)|(1TWSTA)|(1TWEN))#define Stop()  (TWCR=(1TWINT)|(1TWEN)|(1TWSTO))                   #define Wait()  {while(!(TWCR(1TWINT)));}#define TestAck() (TWSR0XF8)#define SetAck   (TWCR|=(1TWEA))#define SetNoAck  (TWCR=~(1TWEA))#define Twi()     (TWCR=(1TWINT)|(1TWEN))//重新启动发送数据   #define Write8Bit(x) {TWDR=(x);TWCR=(1TWINT)|(1TWEN);}//装入SLA_W到TWDR//寄存器,TWINT位清零,启动发送地址//定义运行状态返回值极性#define I2C_ERR   0     //错误#define I2C_CRR   1     //正确//定义TWINT位置位查询等待时间#define WAITCOUNT  50   //3.6864M时,此处必须大于60,验证得知小于60,程序均不能正常工作void twi_init()//硬件初始化{TWBR=0X20;//TWBR的值不小于10TWCR=0X04;//使能TWI操作 TWSR=0;//1分频}uchar IIC_Write(uchar wdata,uchar addr)//字节写操作{//按照时序来写Start();//开始Wait();//等待if(TestAck()!=I2C_START)//测试return 1;// 如果出错则返回1Write8Bit(WD_DEVICE_ADDR);//写器件地址(SLAVE ADDRESS)Wait();//等待if(TestAck()!=I2C_MT_SLA_ACK  )//检验TWI状态寄存器,屏蔽return 1;//预分频位,如果状态字不是SLA+R已发送,收到应答位//转出错处理 ,(SLA针对的是器件地址)此时时序中第一个ACK结束Write8Bit(addr);//写数据地址(要存储到哪个字节上BYTE ADDRESS)Wait();//等待if(TestAck()!=I2C_MT_DATA_ACK )//检验TWI状态寄存器,屏蔽return 1;//预分频位,如果状态字不是写入数据已发送,收到应答位//转出错,到此时序中第二个ACK结束Write8Bit(wdata);//写数据(DATA)Wait();//等待if(TestAck()!=I2C_MT_DATA_ACK)//DATA和ADDRESS是EEPROM内部的就用return 1;   //I2C_MT_DATA_ACKStop();return 0;//运行到STOP处都没有出错就返回0}uchar IIC_Read(uchar addr)//根据选择读时序来写的{uchar temp;//定义此变量从单片机中读取数据//此段与上个函数相同Start();Wait();if(TestAck()!=I2C_START)//测试return 1;//此段与上个函数相同Write8Bit(WD_DEVICE_ADDR);//写器件地址(SLAVE ADDRESS)Wait();if(TestAck()!=I2C_MT_SLA_ACK)//sla是器件外部return 1;//此处时序下方的第一个ACK完成Write8Bit(addr);//写存储地址(BYTE ADDRESS)Wait();if(TestAck()!=I2C_MT_DATA_ACK)//器件内部用I2C_MT_DATA_ACKreturn 1;//此处时序下方的第二个ACK完成Start();//根据时序又出现了STARTWait();if(TestAck()!=I2C_RESTART)//判断是否是重复START出现return 1;//如果出错则返回1Write8Bit(RD_DEVICE_ADDR);//读器件地址(SLAVE ADDRESS)Wait();if(TestAck()!=I2C_MR_SLA_ACK)//现在是主机接收所以不是T而是Rreturn 1;//此处时序下方的第三个ACK完成Twi();//重新启动TWI总线Wait();if(TestAck()!=I2C_MR_DATA_NACK)//向器件里读数据,时序中为NO ACKreturn 1;//程序到了这里数据已经到了单片机里边了temp=TWDR;//从数据寄存器中读取数据Stop();//发送停止信号return temp;}以下是接口函数代码:delay.h:#ifndef delay_h#define delay_hextern void delay(unsigned int ms);#endifdisplay.h:#define  uchar unsigned char#define  uint  unsigned int#ifndef display_h24C02.h:#define  uchar unsigned char#define  uint  unsigned intextern void twi_init();extern uchar IIC_Write(uchar wdata,uchar addr);extern uchar IIC_Read(uchar addr);#define display_hextern void write_com(uchar com);extern void write_dat(uchar dat);extern void LCD_init();extern void display();extern uchar table[];#endif

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top