久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

ATMEGA16—AT24C1024存儲

作者:蕭文   來源:本站原創   點擊數:  更新時間:2014年04月01日   【字體:

總算是把這些問題統統解決了~~

現在貼出來~~

一個哥幫了忙~~

~~

不過以前的錯誤還是有好幾點的~~

AT24C1024存儲:

老規矩~~

顯示上圖~~





然后是程序:(里面有重點要關注的~~)

IAR7_1.c

//------------------------------------------------------------------------------
//IAR7_1.c
//向AT24C1024指定地址寫入一個數據,然后從中讀出來~~
#include"ioavr.h"
#include"lcdinit.h"
#include"at24c1024.h"
#include"delayics.h"
//------------------------------------------------------------------------------
uchar __flash title0[]="Write:";
uchar __flash title1[]="Read:";
uchar __flash test[]="_Justin";
//uchar __flash display[7]={0,0,0,0,0,0,0};
//------------------------------------------------------------------------------
//端口初始化函數
void port_init()
{
  DDRA=0XFF;
  PORTA=0XFF;
  DDRB=0XFF;
  PORTB=0XFF;
 
  DDRC=0XFF;
  PORTC=0X00;
  DDRD=0X00;
  PORTD=0XFF;
}
//------------------------------------------------------------------------------
//main
void main()
{
  uchar display[7];
  port_init();
  twi_init();                          
  lcd_init();
  lcd_display_string(0,0,title0,6);
  lcd_display_string(1,0,title1,5);

 
  mcu_send_string(0xa0,0x00,0x00,test,7);
  delay_s(1);
  mcu_receive_string(0xa0,0x00,0x00,display,7);
 
  lcd_display_string(0,9,test,7);
  lcd_display_char(1,9,display[0]);
  lcd_display_char(1,10,display[1]);
  lcd_display_char(1,11,display[2]);
  lcd_display_char(1,12,display[3]);
  lcd_display_char(1,13,display[4]);
  lcd_display_char(1,14,display[5]);
  lcd_display_char(1,15,display[6]);
  while(1);
}

LCDInit.c

//------------------------------------------------------------------------------
//LCD1602的初始化程序—可調用函數—Atmega 16
#include"ioavr.h"
#include"intrinsics.h"
#include"delayics.h"
#include"bitics.h"
#include"lcdinit.h"
//------------------------------------------------------------------------------
//RS、RW、EN引腳輸出高低電平的宏定義
#define lcd_rs_1  SET_BIT(PORTB,0)          //數據命令選擇端
#define lcd_rs_0  CLR_BIT(PORTB,0)
#define lcd_rw_1  SET_BIT(PORTB,1)          //讀寫命令選擇端         
#define lcd_rw_0  CLR_BIT(PORTB,1)
#define lcd_en_1  SET_BIT(PORTB,2)          //使能信號
#define lcd_en_0  CLR_BIT(PORTB,2)
//------------------------------------------------------------------------------
#define data_port PORTA
#define busy  0x80
//------------------------------------------------------------------------------
//檢測LCD忙函數
void lcd_check_busy()
{
  uchar temp;
  data_port=0xff;
  lcd_rs_0;
  lcd_rw_1;                                 //讀指令
  delay_ms(1);
  lcd_en_1;
  delay_ms(1);
  DDRA=0X00;                                //設置端口A為輸入
  temp=PINA;                                //取端口A的值
  while(temp&busy)                          //當D7為0時可以結束whlie循環,繼續執行下面的操作
    temp=PINA;
  lcd_en_0;
  DDRA=0xff;
}
//------------------------------------------------------------------------------
//LCD寫數據函數
void lcd_write_data(uchar dat)
{
  lcd_check_busy();
  lcd_rs_1;
  lcd_rw_0;
  data_port=dat;
  delay_ms(1);
  lcd_en_1;                                //LCD的使能端高電平有效,當E端由高電平跳變成低電平時,液晶模塊執行命令
  delay_ms(1);                             //送個延時
  lcd_en_0;
}
//------------------------------------------------------------------------------
//LCD寫指令函數
//其中flag的作用是為0不進行忙檢測,為非0則進行忙檢測
void  lcd_write_command(uchar com,uchar flag)
{
  if(flag)
    lcd_check_busy();
  lcd_rs_0;
  lcd_rw_0;
  data_port=com;
  delay_ms(1);
  lcd_en_1;                               //E端由高電平跳變成低電平時,液晶模塊執行命令
  delay_ms(1);                            //送個延時
  lcd_en_0;
}
//------------------------------------------------------------------------------
//LCD初始化函數
//如果Proteus仿真不顯示,那就更改初始化就哦了~~
void lcd_init()
{
  lcd_write_command(0x38,0);   //8位數據傳送,兩行顯示,5*7字形,不檢測忙信號
  delay_ms(3);
  lcd_write_command(0x38,0);
  delay_ms(3);
  lcd_write_command(0x38,0);
  delay_ms(3);
  lcd_write_command(0x38,1);  //8位數據傳送,兩行顯示,5*7字形,檢測忙信號
  lcd_write_command(0x08,1);  //關閉顯示,檢測忙信號
  lcd_write_command(0x01,1);  //清屏,檢測忙信號 
  delay_ms(1);                //一定要有一個延時~~這就是Proteus仿真的差距~~
  lcd_write_command(0x06,1);  //顯示光標右移設置,檢測忙信號
  lcd_write_command(0x0c,1);  //顯示屏打開,光標不顯示,不閃爍,檢測忙信號
}
//------------------------------------------------------------------------------
//LCD顯示一個字節函數
void  lcd_display_char(uchar row,uchar add,uchar dat)
{
  switch(row)
  {
  case 0:
    lcd_write_command(0x80+add,1);
    lcd_write_data(dat);
    break;
    //------------------------------------------------------------------------------
   case 1:
    lcd_write_command(0x80+0x40+add,1);
    lcd_write_data(dat);
    break;
  default:
    break;
  }
}
//------------------------------------------------------------------------------
//LCD顯示多個字節函數
void  lcd_display_string(uchar row,uchar add,uchar __flash *s,uchar num)
{
  uchar i;
  switch(row)
  {
  case 0:
    lcd_write_command(0x80+add,1);
    for(i=0;i<num;i++)
    {
     lcd_write_data(s[i]);
    }
    break;
    //------------------------------------------------------------------------------
   case 1:
    lcd_write_command(0x80+0x40+add,1);
    for(i=0;i<num;i++)
    {
     lcd_write_data(s[i]);
    }
    break;
  default:
    break;
  }
}
AT24C1024.c

//------------------------------------------------------------------------------
//AT24C1024文件的函數,便于以后調用
#include"ioavr.h"
#include"intrinsics.h"
#include"bitics.h"
#include"delayics.h"
#include"lcdinit.h"
//------------------------------------------------------------------------------
typedef unsigned char uchar;
typedef unsigned int  uint;
#define TWINT 7
#define TWEA  6
#define TWSTA 5
#define TWSTO 4
#define TWEN  2
//------------------------------------------------------------------------------
//TWI狀態定義:MT主方式傳輸;MR從方式傳輸
//這里就是與TWI狀態寄存器進行比較的~~如果一致則繼續,如果不一致則終止
//注意:狀態寄存器一定要屏蔽掉預分頻位
#define START 0x08                 //我寫錯了~~
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NOACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NOACK 0x30
#define MR_SLA_ACK 0x40
#define MR_SLA_NOACK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NOACK 0x58
//------------------------------------------------------------------------------
//常用TWI模式操作(主模式寫和主模式讀)
#define twi_start()         (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))      //啟動信號的宏定義
#define twi_stop()          (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))      //停止信號的宏定義
#define twi_wait()          {while(!(TWCR&(1<<TWINT)));}                //等待的宏定義
#define twi_test_ack()      (TWSR&0xf8)                                 //屏蔽掉預分頻位,測試應答信號的宏定義
#define twi_send_ack()      (TWCR|=(1<<TWEA))                           //發送應答信號的宏定義
#define twi_send_noack()    (TWCR&=~(1<<TWEA))                          //發送非應答信號的宏定義
#define twi()               (TWCR=(1<<TWINT)|(1<<TWEN))                 //啟動TWI器件的宏定義
#define twi_write_char(x)   {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}       //發送8位數據的宏定義
//------------------------------------------------------------------------------
//TWI初始化函數
//這個函數我試過~~如果不進行具體的設置可以要也可以不要~~不過也是初始化的一個過程~~所以寫出來~~
void twi_init()
{
  TWBR=0X00;                                        //波特率
  TWSR=0X00;                                        //不分頻
  TWAR=0X00;                                        //被控地址寄存器
  TWCR=(1<<TWEA)|(1<<TWEN);                         //允許ACK,使能IIC,PC0、PC1轉換成SCL、SDA
}
//------------------------------------------------------------------------------
//向器件指定地址按頁寫函數(這里你可以選擇你要寫入的個數num~~)
//寫入成功,返回1;不成功,返回0,使用后必須結束總線
uchar mcu_send_string(uchar add,uchar rom_add_h,uchar rom_add_l,uchar __flash *s,uchar num)
{
  uchar i;
  twi_start();                                      //發送起始信號
  twi_wait();
  if(twi_test_ack()!=START)
    return(0);
 
  twi_write_char(add);                              //發送從器件AT24C1024地址
  twi_wait();
  if(twi_test_ack()!=MT_SLA_ACK)
    return(0);
 
  twi_write_char(rom_add_h);                        //發送器件的ROM地址高字節
  twi_wait();
  if(twi_test_ack()!=MT_DATA_ACK)
    return(0);
 
  twi_write_char(rom_add_l);                        //發送器件的ROM地址低字節
  twi_wait();
  if(twi_test_ack()!=MT_DATA_ACK)
    return(0);
 
  for(i=0;i<num;i++)                               //頁寫,寫入num個數據
  {
    twi_write_char(*s);
    twi_wait();
    if(twi_test_ack()!=MT_DATA_ACK)
      return(0);
    s++;
  }
 
  twi_stop();                                      //發送停止
  delay_ms(2);
  return(1);
}
//------------------------------------------------------------------------------
//從器件指定地址讀多個字節(這里你可以選擇你要讀出的個數num~~)
//寫入成功返回1,不成功返回0
uchar mcu_receive_string(uchar add,uchar rom_add_h,uchar rom_add_l,uchar *s,uchar num)
{
  uchar i;
  twi_start();                                      //發送起始信號
  twi_wait();
  if(twi_test_ack()!=START)
    return(0);
 
  twi_write_char(add);                              //發送從器件AT24C1024地址
  twi_wait();
  if(twi_test_ack()!=MT_SLA_ACK)
    return(0);
 
  twi_write_char(rom_add_h);                        //發送器件的ROM地址高字節
  twi_wait();
  if(twi_test_ack()!=MT_DATA_ACK)
    return(0);
 
  twi_write_char(rom_add_l);                        //發送器件的ROM地址低字節
  twi_wait();
  if(twi_test_ack()!=MT_DATA_ACK)
    return(0);
 
  twi_start();                                      //重新啟動
  twi_wait();
  if(twi_test_ack()!=RE_START)                      //注意:這里必須是RE_START
    return(0);
 
  twi_write_char(add+1);                            //發送從器件AT24C1024地址,這里為讀,要加1
  twi_wait();
  if(twi_test_ack()!=MR_SLA_ACK)                    //注意:這里是MR_SLA_ACK
    return(0);
 
  for(i=0;i<num-1;i++)                              //接收num-1個數據,由于最后一個接收的數據不需要應答,所以要單獨寫   
  {
    twi();
    twi_send_ack();                                 //發送應答位,這里一定要先使能應答位,然后等待~~,出現相應的條件就會發送ACK~~
    twi_wait();
    if(twi_test_ack()!=MR_DATA_ACK)                 //這里是MR_DATA_ACK~~你懂得~~
      return(0);
   
    *s=TWDR;
    s++;
  }
 
  twi();                                          //接收第num個數據
  twi_send_noack();                               //發送非應答位,這里也要先置位~~出現相關條件時發送NOACK
  twi_wait();
  if(twi_test_ack()!=MR_DATA_NOACK)
    return(0);
 
  *s=TWDR;
 
  twi_stop();                                      //TWI停止
  delay_ms(2);
  return(1);
}

關閉窗口

相關文章

主站蜘蛛池模板: 69热视频在线观看 | 天天欧美 | 国内精品久久久久久 | 成人不卡视频 | 久久高清 | 91se在线 | 欧美精品网| 亚洲精品v日韩精品 | 欧美在线视频一区二区 | 国产视频精品在线 | 国产精品夜夜夜一区二区三区尤 | 免费在线一区二区三区 | 欧美成年黄网站色视频 | 午夜精品91 | 国产电影一区二区三区爱妃记 | 激情小视频| 在线国产一区 | 久艹av | 成人不卡视频 | 91久久久久久 | 国产欧美日韩在线一区 | 国产免费一区二区 | 亚洲黄色片免费观看 | 国产999精品久久久 精品三级在线观看 | 91精品久久久久久久久久小网站 | 天天操天天射天天舔 | 亚洲成人毛片 | 久久久久亚洲 | julia中文字幕久久一区二区 | 国产精品国产成人国产三级 | 久久99精品久久久久久国产越南 | 国产97在线视频 | 午夜一区二区三区在线观看 | 国产成人精品在线 | 涩涩鲁亚洲精品一区二区 | 在线观看成年视频 | 国产成人精品一区二区三区在线 | 91精品国产一区二区三区 | 国产传媒 | 精品久久久久久 | 成人av片在线观看 |