找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5052|回复: 4
打印 上一主题 下一主题
收起左侧

芯圣HC89S003F4+rda5807fp+led+红外微电脑高精度可调型数码收音机制作 附程序

[复制链接]
跳转到指定楼层
楼主
本帖最后由 svvv 于 2020-3-6 20:39 编辑

本项目是51单片机入门级别,采用商用低成本单片机制作,电路具有非常高的可靠性和简易调试最小化系统,本项目采用超精简电路,led数码直接又单片机驱动,操作控制有红外遥控器设置功能主要有,往下/往上自动搜索,往下/往上步进100hkz,音量16级调节,具体可在例程中仔细阅读
led 驱动限流电阻Q1-Q4可根据实际情况选用,100-330欧姆,

rda5807左右声道隔直电容47uf-100uf之间选用
                                                                                           rda5807晶振选用晶振32.768khz

其余电源滤波电容0.1uf 和47uf-100uf均可

这款单片机编译需要安装芯圣公司提供的插件环境才可编译,

本例程把i2c驱动分离,具有移植复用性。

本例程由楼主精心调试,但也难免有错误,只做学习单片机交流使用,还提示各位看官请勿拿来大量生产!



全部资料51hei下载地址:
程序: rda5807Project.zip (11.04 KB, 下载次数: 104)
原理图: rda5807Projectpcb.zip (12.88 KB, 下载次数: 61)


单片机源程序如下:

  1. /**
  2. *   ************************************************************************************
  3. *                                        微电脑数控型收音机i2c工程                        
  4. *                                                        
  5. *        ************************************************************************************
  6. *        @Examle Version                V0.0.0.1
  7. *        @Demo         Version                V0.0.0.1
  8. *        @Date                                2019.07.22
  9. *        ************************************************************************************
  10. *   ************************************************************************************
  11. **/


  12. #define        ALLOCATE_EXTERN
  13. #include "HC89S003F4.h"
  14. #include<intrins.h>
  15. #include "iic.h"
  16. #include "radio.h"

  17.         
  18. uchar duan[11]={0x77,0x11,0x6b,0x3b,0x1d,0x3e,0x7e,0x13,0x7f,0x3f,0x75};
  19.         
  20. uchar Display_FM[8];
  21. extern  unsigned char  RDA_reg_data[8];

  22. unsigned char IR_code[4] = {0,0,0,0};//存放四组数据


  23. uchar         zd=0;         //
  24. sbit          IR_Out=P0^7; //HS0038接收头OUT端直接连P3.2(INT0)

  25. /**************************延时0.9ms子程序**********************/


  26. void Delay_ms(unsigned int fui_i)
  27. {
  28.         unsigned int fui_j;
  29.         for(;fui_i > 0;fui_i --)
  30.         for(fui_j = 1596;fui_j > 0;fui_j --);
  31. }




  32. void DelayUs(uint us)
  33. {
  34.         for(; us>0; us--)
  35.         {
  36.                 _nop_();
  37.                 _nop_();
  38.                 _nop_();
  39.         }        
  40. }

  41. /**************************** 延时子程序 ************************/
  42. void Delay(void)
  43. {
  44.     uchar i,j,k;
  45.     for(i=200;i>0;i--)
  46.         for(j=200;j>0;j--)
  47.             for(k=3;k>0;k--) ;
  48. }               
  49. void DigDisplay()
  50. {
  51.         uchar i;
  52.          uchar smgduan[4];                                
  53.                                                    smgduan[0]=duan[Display_FM[0]];
  54.                                                   smgduan[1]=duan[Display_FM[1]];
  55.                                                   smgduan[2]=duan[Display_FM[2]]+0x80;
  56.                                                   smgduan[3]=duan[Display_FM[3]];
  57.                                                   P2=0x00;//消隐
  58.         for(i=0;i<4;i++)
  59.         {
  60.                 switch(i)         //位选,选择点亮的数码管,
  61.                 {
  62.                         case(0):
  63.                                 P0_2=0;P0_3=1;P0_4=1;P0_5=1; break;//显示第0位
  64.                         case(1):
  65.                                  P0_2=1;P0_3=0;P0_4=1;P0_5=1; break;//显示第1位
  66.                         case(2):
  67.                                 P0_2=1;P0_3=1;P0_4=0;P0_5=1; break;//显示第2位
  68.                         case(3):
  69.                                  P0_2=1;P0_3=1;P0_4=1;P0_5=0; break;//显示第3位

  70.                 }
  71.                 P2=smgduan[i];//发送段码
  72.                                 Delay_ms(1); //间隔一段时间扫描        
  73.                 P2=0x00;//消隐
  74.         }
  75. }
  76.                
  77. /***************************************************************************************
  78.   * @实现效果        对P00口进行高、低电平转换,LED1不断翻转
  79. ***************************************************************************************/
  80. void main()
  81. {                uchar i;

  82.         WDTCCR = 0x00;                                                //关闭看门狗
  83.                                             //本例程为方便测试关闭看门狗,实际使用中,建议客户打开看门狗,详见WDT复位
  84.         CLKSWR = 0x51;                                                //选择内部高频RC为系统时钟,内部高频RC 2分频,Fosc=16MHz
  85.         CLKDIV = 0x01;                                                //Fosc 1分频得到Fcpu,Fcpu=16MHz
  86.                 IIC_GPIO_Init();

  87. //        P2M0 = P2M0&0x0F|0x80;                                      //P21设置为推挽输出
  88. //        P0M1 = P0M1&0x0F|0x20;                                      //P03设置为上拉输入
  89. //        TXD_MAP = 0x21;                                                          //TXD映射P21
  90. //        RXD_MAP = 0x03;                                                          //RXD映射P03               
  91. //        T4CON = 0x06;                                                            //T4工作模式:UART1波特率发生器

  92.           P0M1 = P0M1&0x00|0x88;                //P1.0.1设置为推挽输出
  93.           P0M2 = P0M2&0x00|0x88;                //P1.0.1设置为推挽输出
  94.                                                                                                                     
  95. //          P0M0 = P0M0&0xf0|0x0a;                //P1.0.1设置为推挽输出
  96. //          P1M0 = P1M0&0x0f|0xa0;                //P2.0.1设置为推挽输出
  97.             
  98.            P2M0 = P2M0&0x00|0x88;                //P1.0.1设置为推挽输出
  99.           P2M1 = P2M1&0x00|0x88;                //P1.0.1设置为推挽输出
  100.           P2M2 = P2M2&0x00|0x88;                //P1.0.1设置为推挽输出
  101.           P2M3 = P2M3&0x00|0x88;                //P1.0.1设置为推挽输出

  102. //                P0M0 = P0M0&0xF0|0x08;                //P00设置为推挽输出
  103.         P0M3 = P0M3&0x0F|0x00;                //P27设置为带SMT输入
  104.         PITS1 |= 0x40;                                                //INT15下降沿中断
  105.         PINTE0 |= 0x80;                                                //使能INT15
  106.         IE1 |= 0x40;                                                  //打开INT8-15中断
  107. //        EA = 1;                                                                    //打开总中断
  108.                   

  109. //    TH4 = 0xFF;
  110. //        TL4 = 0x98;                                                                     //波特率9600
  111. //        SCON2 = 0x02;                                                             //8位UART,波特率可变
  112. //        SCON = 0x10;                                                       //允许串行接收
  113. //        IE |= 0X10;                                                                     //使能串口中断
  114.         EA = 1;        

  115.                   
  116.                 RDA5807_power();

  117.         RDA_set(1077);  
  118.                           
  119.         while(1){

  120.                          show_frequency();
  121.                          DigDisplay();        
  122.                           
  123.                  
  124.                           if(zd==1){
  125.                           
  126.                                    if(IR_code[2]==0x07){
  127.                                              RDA_reg_data[0] &= ~(1 << 1);  //SEEK DOWN
  128.                                            RDA5807_FM_seek();
  129.                                  }else if(IR_code[2]==0x03){
  130.                                        RDA_reg_data[0] |= (1 << 1); //SEEK UP  
  131.                                                 RDA5807_FM_seek();
  132.                                           
  133.                                  }else if(IR_code[2]==0x0b){
  134.                                    
  135.                                         setup(1);
  136.                                  }else if(IR_code[2]==0x50){
  137.                                    
  138.                                         setup(0);
  139.                                  }else if(IR_code[2]==0x0f){
  140.                                          setvol(0);
  141.                                          i=100;
  142.                                         while(i--){
  143.                                         show_vol();
  144.                                         DigDisplay();
  145.                                                                 }
  146.                                  }else if(IR_code[2]==0x13){
  147.                                          setvol(1);
  148.                                          i=100;
  149.                                         while(i--){
  150.                                         show_vol();
  151.                                         DigDisplay();
  152.                                                                 }
  153.                                  }

  154.                                   zd=0;
  155.                           }
  156.                   
  157.                                    
  158.                                 
  159.                         
  160.                
  161.                         
  162.         }                        
  163.                  


  164. }        
  165.                         
  166. /************************中断0解码服务子程序**********************/
  167. void int0(void) interrupt INT2_7_VECTOR
  168. {
  169.      unsigned char i,j;

  170.                  
  171.          EA = 0;  
  172.             if(PINTF0&0x80)                                                //判断INT15中断标志位
  173.         {
  174.                   PINTF0 &=~ 0x80;        
  175.         
  176.             // 关闭外部中断0
  177.            
  178.             i = 10;    // 0.793ms延时,运行10次
  179.      while( --i )
  180.      {
  181.           // 定时0.793ms,延时0.793ms*10=7.93ms
  182.           DelayUs(800);
  183.           // 这7.93ms期间只要IR_Out变高电平,就非合法的红外信号,跳出
  184.           if( IR_Out )
  185.           {          //          P0_0= 1;
  186.                EA = 1; // 准许中断
  187.                         
  188.                return ;
  189.           }
  190.      }
  191.          //        P0_0=1;
  192. // 程序进行到这里,表明是合法的红外信号(利用9ms判断)
  193. while( !IR_Out ); // 等待9ms低电平过去
  194. // 程序进行到这里,表明经过9ms低电平
  195. Delay_ms(2);     // 延时2.305ms
  196. DelayUs(300);
  197. // IR_Out 为低表明是连发码,不予理睬,跳出
  198.             
  199. if( !IR_Out )
  200. {         //  P0_0=0;
  201.       EA=1;
  202.       return;
  203. }                        
  204. // 程序进行到这里,表明是引导码,等待4.5ms高电平的过去
  205. while( IR_Out );
  206. // 开始接收四组数据
  207. for(i=0; i<4; i++)
  208.   {                  //   P0_0=1;
  209.       for(j=0; j<8; j++)
  210.       {
  211.            while( !IR_Out ); // 等待低电平过去
  212.                IR_code[ i] >>= 1;  // 把上次的数据位右移一位
  213.          DelayUs(800);     //延时0.793ms
  214.        // 若为数据"1",则延时后IR_Out为高电平
  215.          if( IR_Out )
  216.           {
  217.                 IR_code[ i] |= 0x80;  // 所有数据位1放最高位
  218.                 while( IR_Out ); // 等待高电平过去
  219.           }
  220.       }
  221.    }  
  222. //IR_code[0]低8位用户码,IR_code[1]高8位用户码,IR_code[2]为数据码,IR_code[3]为数据反码----dat为二进制
  223.   if (IR_code[2]!=~IR_code[3]) //数据码校验
  224.     {
  225.           EA=1;
  226.           return;
  227.      }


  228.             for(i=0;i<4;i++)        //通过串口将代码发出
  229.             {
  230.                 SBUF=IR_code[i];
  231.                 while(!TI);       //等待一个字节发送完毕
  232.                 TI=0;
  233.             }




  234.         zd=1;

  235.           EA=1;  // 开中断
  236.         return;
  237.            
  238.         }                                
  239.         }
  240.         
  241.         
  242. void UART1_Rpt(void) interrupt UART1_VECTOR
  243. {
  244.         if(SCON & 0x01)                                                            //判断接收中断标志位
  245.         {
  246.         /*        guc_Uartbuf_a[guc_Uartcnt++] = SBUF;//转存8位串口接收数据
  247.                 if(guc_Uartcnt >= 5)
  248.                 {
  249.                         SCON &=~ 0x10;                                            //失能UART1接收
  250.                         guc_Uartflag = 1;
  251.                 } */
  252.                   SCON &=~ 0x01;                                                    //清除接收中断标志位
  253.         }                                                                        
  254. }                                                                                                                                                                                       







  255. /**
  256. *   ************************************************************************************
  257. *                                        微电脑数控型收音机i2c工程                        
  258. *                                                        
  259. *        ************************************************************************************
  260. *        @Examle Version                V0.0.0.1
  261. *        @Demo         Version                V0.0.0.1
  262. *        @Date                                2019.07.22
  263. *        ************************************************************************************

  264. *   ************************************************************************************
  265. **/

  266. //radio.h

  267. #ifndef _radio_h
  268. #define _radio_h

  269. void RDA5807_write_reg(void);
  270. void RDA5807_read_reg(unsigned char *reg_buf) ;
  271. void RDA5807_power(void) ;
  272. void RDA5807_FM_seek(void);
  273. void show_frequency(void);

  274. void show_volume(void);

  275. void RDA_set(unsigned int p);

  276. void  setup(unsigned char u);  
  277. void setvol(uchar temp);
  278. void  show_vol(void);
  279. void RDA5807_write_reg_byte(unsigned char add,unsigned char temp,unsigned char temp1);
  280. #endif


  281. /**
  282. *   ************************************************************************************
  283. *                                        微电脑数控型收音机i2c工程                        
  284. *                                                        
  285. *        ************************************************************************************
  286. *        @Examle Version                V0.0.0.1
  287. *        @Demo         Version                V0.0.0.1
  288. *        @Date                                2019.07.22
  289. *        ************************************************************************************

  290. *   ************************************************************************************
  291. **/

  292. //radio.c
  293.     #include "HC89S003F4.h"
  294.         #include "iic.h"

  295. #include "delay.h"
  296. #include "radio.h"


  297. extern uchar data Display_FM[8];

  298. extern void DigDisplay();


  299. #define RDA_R00 0X00;
  300. #define RDA_R02 0X02;
  301. #define RDA_R03 0X03;
  302. #define RDA_R04 0X04;
  303. #define RDA_R05 0X05;
  304. #define RDA_READ 0X23;
  305. #define RDA_WRITE 0X22;

  306. //初始化寄存器
  307. unsigned char  RDA_reg_data[8] =
  308. {
  309.    0x00,0x00,  // 02H
  310.    0x00,0x00,  // 03H
  311.    0x00,0x00,  // 04H
  312.    0x00,0x00,  // 05H
  313. };
  314. //收音模块单字节写入操作
  315. void RDA5807_write_reg_byte(unsigned char add,unsigned char temp,unsigned char temp1){
  316.    IIC_Start();
  317.    IIC_Send_Byte(0x22);
  318.    IIC_Send_Byte(add);
  319.    IIC_Send_Byte(temp);
  320.    IIC_Send_Byte(temp1);
  321.    IIC_Stop();
  322. }

  323.   //连续写寄存器子函数
  324. void RDA5807_write_reg(void)
  325. {
  326.    uchar i;

  327.    IIC_Start(); //收音模块写入操作
  328.    IIC_Send_Byte(0x20);
  329.           for(i=0; i<8; i++)
  330.    {
  331.      IIC_Send_Byte(RDA_reg_data[i]);
  332.    }

  333.    IIC_Stop();
  334. }


  335. void RDA5807_read_reg(uchar *reg_buf) //连续读寄存器子函数
  336. {
  337.         IIC_Start();
  338.         IIC_Send_Byte(0x21); //寄存器连续读操作
  339.         reg_buf[0] = IIC_Read_Byte(1);
  340.         reg_buf[1] = IIC_Read_Byte(1);
  341.         reg_buf[2] = IIC_Read_Byte(1);
  342.         reg_buf[3] = IIC_Read_Byte(0);
  343.         IIC_Stop();
  344. }


  345. void RDA5807_power(void) //模块上电初始化子函数
  346. {
  347.         Delay_ms(700);
  348.         RDA_reg_data[0] = 0x00; //发送软件复位指令
  349.         RDA_reg_data[1] = 0x02;
  350.         RDA5807_write_reg();
  351.         Delay_ms(50);
  352.         RDA_reg_data[0] = 0x00; //发送软件复位指令
  353.         RDA_reg_data[1] = 0x01;
  354.         RDA5807_write_reg();
  355.         Delay_ms(700);


  356.         RDA_reg_data[0] = 0xc0; //收音模块默认参数
  357.         RDA_reg_data[1] = 0x01;

  358.         RDA_reg_data[4] = 0x00; //收音模块默认参数
  359.         RDA_reg_data[5] = 0x00;        
  360.         RDA_reg_data[6] = 0x85; //收音模块默认参数 强度
  361.         RDA_reg_data[7] = 0x88;        


  362.         RDA_reg_data[3] |= 0x10; //调谐启用
  363.         RDA5807_write_reg();                     
  364.         
  365.    Delay_ms(40);
  366. }  
  367.   //设置指定频率
  368. void RDA_set(uint p){
  369.         uint temp;

  370.         temp=(uint)(p-870);
  371.         temp&=0x03ff;
  372.         temp=temp<<6;
  373.         temp|=1<<4;
  374.         RDA_reg_data[2]=temp>>8;
  375.         RDA_reg_data[3]=temp;
  376.         RDA5807_write_reg();
  377.         Delay_ms(10);
  378. }
  379.                  
  380. void RDA5807_FM_seek(void) //功能描述:收音模块自动寻台模式
  381. {
  382.   uint temp;
  383.    uchar  reg_data[4] = {0x00, 0x00, 0x00, 0x00};

  384.         RDA_reg_data[3] &= ~(1 << 4); //调谐禁用 内部自动寻台使   
  385.         RDA_reg_data[0] |=  (1 << 0);      //SEEK位置        1
  386.         RDA5807_write_reg();
  387.         while(0 == (reg_data[0] & 0x40))  //等待 STC          标志置位
  388.     {
  389.         Delay_ms(30);
  390.                 RDA5807_read_reg(reg_data); //读取内部状态               
  391.         }         

  392.         temp = reg_data[0] & 0x03; //获取当前工作频点
  393.         temp = reg_data[1] | (temp << 8);
  394.         temp = temp << 6;         
  395.         RDA_reg_data[2] = (temp >> 8) & 0xff; //保存当前工作频点
  396.         RDA_reg_data[3] = (temp & 0xff);
  397.         
  398. }
  399.          
  400. void  show_frequency(void) //频率显示函数
  401. {  
  402.         unsigned char i;
  403.         unsigned int  temp;
  404.          


  405.          temp = (RDA_reg_data[2]*256)+(RDA_reg_data[3]&0xc0); //计算
  406.         temp = temp>>6;
  407.         temp = (unsigned int)(temp+870);
  408.         
  409.         for(i=0; i<4; i++){  
  410.         Display_FM[i] = 0x00; //清显存单元
  411.         }
  412.         Display_FM[0] = (temp)/1000  ; //数据转换
  413.         Display_FM[1] = (temp%1000)/100;
  414.         Display_FM[2] = (temp%100)/10;

  415.         Display_FM[3] = (temp%10);                        
  416.                

  417. }


  418. void  show_vol(void) //vol显示函数
  419. {  
  420.         unsigned char i;
  421.         unsigned int  temp;
  422.          


  423.          temp = (RDA_reg_data[7]& 0x0f); //计算
  424.         
  425.         for(i=0; i<4; i++){  
  426.         Display_FM[i] = 0x00; //清显存单元
  427.         }
  428.         Display_FM[0] = 10  ; //数据转换
  429.         Display_FM[1] = 0;
  430.         Display_FM[2] = (temp%100)/10;

  431.         Display_FM[3] = (temp%10);                        
  432.                

  433. }
  434. //设定频率上下步进100khz
  435. void  setup(uchar u)
  436. {  

  437.         unsigned int  temp;

  438.          temp = (RDA_reg_data[2]*256)+(RDA_reg_data[3]&0xc0); //计算
  439.         temp = temp>>6;
  440.     if(u==1){
  441.         temp=temp+1;
  442.                 if(temp>0xd2)
  443.                    temp=0;
  444.         }else if(u==0){
  445.             if(temp==0){
  446.                 temp=0xd2;
  447.                 }else{
  448.                 temp=temp-1;
  449.             }
  450.         }
  451.         temp&=0x03ff;
  452.         
  453.         
  454.         temp=temp<<6;
  455.         
  456.         temp|=1<<4;        
  457.         RDA_reg_data[2]=temp>>8;
  458.         RDA_reg_data[3]=temp;
  459.         RDA5807_write_reg();
  460.         Delay_ms(10);

  461. }
  462. //设定音量上下16级
  463. void setvol(uchar u){

  464.                 if(u==1){
  465.                  if((RDA_reg_data[7] & 0x0f) < 0x0f)
  466.          {
  467.                            RDA_reg_data[3] |= 0x10; //调谐启用
  468.            RDA_reg_data[7]++; //音量递增
  469.                   RDA5807_write_reg_byte(0X05,RDA_reg_data[6],RDA_reg_data[7]);
  470.                    }
  471.            }else if(u==0){

  472.                 if((RDA_reg_data[7] & 0x0f) > 0x00)
  473.          {
  474.                            RDA_reg_data[3] |= 0x10; //调谐启用
  475.            RDA_reg_data[7]--; //音量递增

  476.                               RDA5807_write_reg_byte(0X05,RDA_reg_data[6],RDA_reg_data[7]);  
  477.                    }

  478.            }

  479. }                                                                           



  480. /**
  481. *   ************************************************************************************
  482. *                                        微电脑数控型收音机i2c工程                        
  483. *                                                        
  484. *        ************************************************************************************
  485. *        @Examle Version                V0.0.0.1
  486. *        @Demo         Version                V0.0.0.1
  487. *        @Date                                2019.07.22
  488. *        ************************************************************************************
  489. *                                                         

  490. *   ************************************************************************************
  491. **/

  492. //IIC.h
  493. #ifndef __IIC_H__
  494. #define __IIC_H__

  495. #include "HC89S003F4.h"
  496. #include "intrins.h"

  497. #define IIC_SDA  P0_0     //模拟IIC数据线
  498. #define IIC_SCL  P1_1          //模拟IIC时钟线

  499. #define IIC_WR        0              // 写控制bit
  500. #define IIC_RD        1              // 读控制bit
  501.                                             
  502. #define IIC_SDA_L         P0_0=0    //SDA拉低     
  503. #define IIC_SDA_H         P0_0=1    //SDA拉高 CH1

  504. #define IIC_SCL_L         P1_1=0        //SCL拉低 CH2
  505. #define IIC_SCL_H         P1_1=1    //SCL拉高

  506. #define IIC_SDA_IN()           {P0M0 = P0M0&0xf0|0x04;}   //设置SDA     SMT输入
  507. #define IIC_SDA_OUT()           {P0M0 = P0M0&0xf0|0x08;}   //设置SDA    推挽输出
  508. #define IIC_SCL_OUT()    {P1M0 = P1M0&0x0f|0x80;}   //设置SCL    推挽输出
  509.                                                                                                                                    
  510. void IIC_GPIO_Init(void);  //IIC GPIO初始化
  511. void IIC_Start();   //启动I2C总线
  512. void IIC_Stop();    //停止I2C总线
  513. void Delay_IIC();//IIC延时
  514. unsigned char IIC_Send_Byte(unsigned char txd);                        //IIC发送一个字节
  515. unsigned char IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
  516. unsigned char IIC_Wait_Ack(void);                                 //IIC等待ACK信号
  517. void IIC_Ack(void);                                        //IIC发送ACK信号
  518. void IIC_NAck(void);                                //IIC不发送ACK信号




  519. #endif/* __IIC_H__ */


  520. /**
  521. *   ************************************************************************************
  522. *                                        微电脑数控型收音机i2c工程                        
  523. *                                                        
  524. *        ************************************************************************************
  525. *        @Examle Version                V0.0.0.1
  526. *        @Demo         Version                V0.0.0.1
  527. *        @Date                                2019.07.22
  528. *        ************************************************************************************
  529. *                                                         
  530. *        若发现错误或对函数的使用存在疑问。请添加:51单片机电子交流群
  531. *                                                ****************************

  532.                                                         技术交流群:879778027

  533.                                                 ***********************************
  534. *   ************************************************************************************
  535. **/

  536. //IIC.c
  537. #include "IIC.h"



  538. void Delay_IIC()//IIC延时
  539. {
  540.    _nop_();_nop_();_nop_();_nop_();

  541. }


  542. void IIC_GPIO_Init()  //IIC初始化子程序
  543. {
  544.         IIC_SCL_OUT();
  545.         IIC_SDA_OUT();
  546.         IIC_Stop();
  547. }

  548. void IIC_Start()   //启动I2C总线
  549. {
  550.     IIC_SDA_OUT();
  551.     IIC_SDA_H;           //拉高SDA
  552.         Delay_IIC(); //延时
  553.         IIC_SCL_H;           //拉高SCL
  554.         Delay_IIC(); //延时
  555.         IIC_SDA_L;           //拉低SDA
  556.         Delay_IIC(); //延时
  557.         IIC_SCL_L;           //拉低SCL
  558.         Delay_IIC(); //延时
  559. }

  560. void IIC_Stop()    //停止I2C总线
  561. {
  562.     IIC_SDA_OUT();
  563.         IIC_SDA_L;           //拉低SDA
  564.         IIC_SCL_H;           //拉高SCL
  565.         Delay_IIC(); //延时
  566.     IIC_SDA_H;           //拉高SDA
  567.         Delay_IIC(); //延时
  568. }

  569. //等待应答信号到来
  570. //返回值:1,接收应答失败
  571. //        0,接收应答成功
  572. unsigned char IIC_Wait_Ack(void)
  573. {
  574.         unsigned char ucErrTime=0;
  575.         IIC_SDA_IN();     //SDA设置为输入  
  576.         IIC_SDA_H;        Delay_IIC(); //延时           
  577.     IIC_SCL_H;        Delay_IIC(); //延时;         
  578.         while(IIC_SDA!=0)
  579.         {
  580.                 ucErrTime++;
  581.                 if(ucErrTime>250)
  582.                 {
  583.                         IIC_Stop();
  584.                         return 1;
  585.                 }
  586.         }
  587.     IIC_SCL_L;//时钟输出0            
  588.         return 0;  
  589. }

  590. //产生ACK应答
  591. void IIC_Ack(void)
  592. {
  593.     IIC_SCL_L;
  594.     IIC_SDA_OUT();
  595.     IIC_SDA_L;
  596.     Delay_IIC(); //延时         
  597.     IIC_SCL_H;
  598.     Delay_IIC(); //延时
  599.     IIC_SCL_L;
  600. }

  601. //不产生ACK应答                    
  602. void IIC_NAck(void)
  603. {
  604.     IIC_SCL_L;
  605.     IIC_SDA_OUT();
  606.     IIC_SDA_H;
  607.     Delay_IIC(); //延时
  608.     IIC_SCL_H;
  609.     Delay_IIC(); //延时
  610.     IIC_SCL_L;
  611. }

  612. //IIC发送一个字节
  613. //返回从机有无应答
  614. //1,有应答
  615. //0,无应答                          
  616. unsigned char IIC_Send_Byte(unsigned char txd)
  617. {                        
  618.     unsigned char  t;   
  619.     IIC_SDA_OUT();            
  620.     IIC_SCL_L;;//拉低时钟开始数据传输
  621.     for(t=0;t<8;t++)
  622.     {              
  623.                 if((txd&0x80)>>7)
  624.         IIC_SDA_H;
  625.                 else
  626.         IIC_SDA_L;
  627.                   txd<<=1;           
  628.         Delay_IIC(); //延时
  629.                 IIC_SCL=1;
  630.         Delay_IIC(); //延时
  631.                 IIC_SCL=0;        
  632.         Delay_IIC(); //延时
  633.     }
  634.         IIC_Wait_Ack();         
  635. }         

  636. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  637. unsigned char IIC_Read_Byte(unsigned char ack)
  638. {
  639.         unsigned char i,receive=0;
  640.         IIC_SDA_IN();//SDA设置为输入
  641.         IIC_SCL_L;//拉低时钟开始数据传输
  642.     IIC_SDA=1;
  643.         for(i=0;i<8;i++ )
  644.         {
  645.         receive<<=1;
  646.         IIC_SCL_H;
  647.               Delay_IIC(); //延时
  648.         if(IIC_SDA!=0)
  649.                 receive++;   
  650.                    IIC_SCL_L;
  651.         Delay_IIC(); //延时
  652.     }                                         
  653.     if (!ack)
  654.         IIC_NAck();//发送nACK
  655.     else
  656.         IIC_Ack(); //发送ACK   
  657.     return receive;
  658. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:702074 发表于 2020-3-4 19:24 | 只看该作者
更新一处错误:
//radio.c
中的
#include "delay.h"
替换成
extern void Delay_ms(unsigned int fui_i);
即可正常编译

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:280405 发表于 2020-3-4 20:48 | 只看该作者
mark!谢谢分享
回复

使用道具 举报

地板
ID:730824 发表于 2020-4-21 16:43 | 只看该作者
WOC这竟然是入门级别 看来我还没入门
回复

使用道具 举报

5#
ID:704585 发表于 2020-4-24 14:10 | 只看该作者
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表