[PIC®/AVR®/dsPIC®产品] PIC18F2520驱动RDA5807方案

[复制链接]
 楼主| 玛尼玛尼哄 发表于 2024-9-27 22:44 | 显示全部楼层 |阅读模式
游客,如果您要查看本帖隐藏内容请回复

是一个非常简单的固件,用于控制RDA5807 I2C 无线电 ic。
  • 2x16 LCD 显示屏。
  • 存储 6 个内存位置。
  • RDS 就绪。
  • 音量控制。




  1. /*
  2.     File:   main.c
  3.     Copyright 2016 Marcos Mori de Siqueira <mori.br@gmail.com>

  4.     Licensed under the Apache License, Version 2.0 (the "License");
  5.     you may not use this file except in compliance with the License.
  6.     You may obtain a copy of the License at

  7.        http://www.apache.org/licenses/LICENSE-2.0

  8.     Unless required by applicable law or agreed to in writing, software
  9.     distributed under the License is distributed on an "AS IS" BASIS,
  10.     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11.     See the License for the specific language governing permissions and
  12.     limitations under the License.
  13. */
  14. //#include <p18cxxx.h>
  15. #include <p18f2520.h>
  16. #include <delays.h>
  17. #include <usart.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <i2c.h>
  22. #include <timers.h>
  23. #include "rda5807.h"
  24. #include "hardwareprofile.h"
  25. #include "LCDBlocking.h"
  26. #include "TimeDelay.h"
  27. #include "keypad.h"
  28. #include "log.h"
  29. #include "eeprom.h"
  30. #include "rds.h"
  31. #include "options.h"
  32. #include "test.h"
  33. #include <math.h>

  34. #pragma config OSC    = HS
  35. #pragma config WDT    = OFF
  36. #pragma config LVP    = OFF
  37. #pragma config MCLRE  = ON
  38. #pragma config PWRT   = ON
  39. #pragma config PBADEN = OFF

  40. #define MAX_VOLUME          0x0C    //0x0F

  41. #define SAVE_TIMEOUT        5000
  42. #define BACK2IDLE_TIMEOUT   1000
  43. #define MENU_TIMEOUT        50000

  44. #define STATE_IDLE          0
  45. #define STATE_VOLUME        1
  46. #define STATE_MEMORY        2
  47. #define STATE_MENU          3
  48. #define STATE_LAST_BASIC    3
  49. #define STATE_LAST          4

  50. static BYTE mem_idx = 0;
  51. static BYTE state = STATE_IDLE;
  52. static LONG state_timeout = 0;

  53. extern volatile RDSINFO rds;
  54. static RDAINFO info;

  55. typedef struct
  56. {
  57.     RDA_MEMORY mem;
  58.     LONG mem_save_timeout;
  59.     BYTE enabled;
  60.    
  61. } SAVEINFO;

  62. static SAVEINFO save_info = {{0},0,0};

  63. static void update_lcd(void);
  64. static void process_dn(void);
  65. static void process_up(void);
  66. static BYTE setup_memory(void);

  67. void main(void)
  68. {   
  69.     char *c = 0;
  70.     DWORD counter = 0, read = 0;
  71.     BYTE  evt;
  72.     DWORD ellapsed = 0;
  73.     BYTE  btn_ok_pressed = 0;
  74.    
  75.     CMCON   = 0x07; // Comparators Off
  76.     CVRCON  = 0;    // voltage reference=off
  77.     ADCON1  = 0x0F; // Disable ALL adc channels, PDF page 226
  78.    
  79.     LED1_TRIS    = OUTPUT_PIN;
  80.         I2C_SCL_TRIS = OUTPUT_PIN;
  81.         I2C_SDA_TRIS = OUTPUT_PIN;
  82.    
  83.     // Uart
  84.     OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 10);

  85.     LOG((ROMCHAR)"\r\n-------------------------------------------------\r\n");
  86.    
  87.     KeypadInit();
  88.    
  89.     LCDInit();
  90.   
  91.     // Setup I2C
  92.     OpenI2C(MASTER, SLEW_OFF);
  93.     //SSPADD = 0x32; //100kHz Baud clock @20MHz
  94.     SSPADD = 0x0B;//400kHz Baud clock @20MHz
  95.    
  96.     LCDErase();
  97.     strcpypgm2ram(c, (ROMCHAR)"    STARTING    ");
  98.     LCDWriteLine(1, c);
  99.    
  100.     memset(save_info.mem.data, 0, sizeof(RDA_MEMORY));

  101. //TEST_eeprom_reset();

  102.     if(!EEPROM_load_data(&save_info.mem))
  103.     {
  104. LOG((ROMCHAR)"loading default config\r\n");
  105.         save_info.mem.flags   = RDA_FLAG_RDS|RDA_FLAG_BASS;
  106.         save_info.mem.channel = 101.7;
  107.         save_info.mem.volume  = 1;

  108. //save_info.mem.memory[0] = 97.7;
  109. //save_info.mem.memory[3] = 103.3;
  110. //save_info.mem.memory[4] = 90.5;
  111.     }
  112.    
  113.     LOG((ROMCHAR)"init\r\n");   
  114.     RDA5807M_init();

  115.     RDA5807M_PowerON();
  116.    
  117.     DelayMs(200);

  118.     // Setup radio
  119.     RDA5807M_SetVolume(save_info.mem.volume);
  120.     RDA5807M_SetFrequency(save_info.mem.channel);
  121.     RDA5807M_BassBoost(save_info.mem.flags & RDA_FLAG_BASS);
  122.     RDA5807M_Mono(save_info.mem.flags & RDA_FLAG_MONO);
  123.     RDA5807M_RDS(save_info.mem.flags & RDA_FLAG_RDS);
  124.    
  125.         while(1)
  126.         {
  127.         LED1 = 0;
  128.         if(counter++ > 3000)
  129.         {
  130.             counter = 0;
  131.             LED1 = 1;
  132.             DelayMs(10);
  133.         }

  134.         evt = GetButtonsEvents();
  135.              if(evt != EVENT_NOTHING)
  136.               {
  137.                         if(evt == EVENT_UP_BUTTON_PUSHED)
  138.                         {
  139.                 if(state != STATE_MENU)
  140.                 {
  141. //LOG((ROMCHAR)"up %d\r\n", state);                    
  142.                     if(++state >= STATE_LAST_BASIC)
  143.                         state = STATE_IDLE;
  144. //LOG((ROMCHAR)"up %d\r\n", state);
  145.                     
  146.                     if(state == STATE_MEMORY)
  147.                         mem_idx = setup_memory();
  148.                     
  149.                     if(state > STATE_IDLE)
  150.                         state_timeout = BACK2IDLE_TIMEOUT;
  151.                     else
  152.                     {
  153.                         state_timeout = 0;
  154.                         rds.ps_valid = 1;
  155.                         rds.rt_valid = 1;
  156.                     }
  157.                 }
  158.                 else
  159.                 {
  160.                     state_timeout = MENU_TIMEOUT;
  161.                     MENU_run(MENU_UP);
  162.                 }
  163.                         }
  164.                         else if(evt == EVENT_DN_BUTTON_PUSHED)
  165.                         {
  166.                 if(state != STATE_MENU)
  167.                 {
  168. //LOG((ROMCHAR)"dn %d\r\n", state);                    
  169.                     if(--state >= 0xFF)
  170.                         state = STATE_IDLE;
  171. //LOG((ROMCHAR)"dn %d\r\n", state);
  172.                     if(state > STATE_IDLE)
  173.                         state_timeout = BACK2IDLE_TIMEOUT;
  174.                     else
  175.                     {
  176.                         state_timeout = 0;
  177.                         rds.ps_valid = 1;
  178.                         rds.rt_valid = 1;
  179.                     }
  180.                 }
  181.                 else
  182.                 {
  183.                     state_timeout = MENU_TIMEOUT;
  184.                     MENU_run(MENU_DOWN);
  185.                 }
  186.                         }
  187.                         else if(evt == EVENT_LEFT_BUTTON_PUSHED)
  188.                         {
  189.                 //LOG((ROMCHAR)"left\r\n");
  190.                 if(state == STATE_MENU)
  191.                 {
  192.                     state_timeout = MENU_TIMEOUT;
  193.                     MENU_run(MENU_LEFT);
  194.                 }
  195.                 else
  196.                     process_dn();
  197.                         }   
  198.                         else if(evt == EVENT_RIGHT_BUTTON_PUSHED)
  199.                         {
  200.                 //LOG((ROMCHAR)"right\r\n");
  201.                 if(state == STATE_MENU)
  202.                 {
  203.                     state_timeout = MENU_TIMEOUT;
  204.                     MENU_run(MENU_RIGHT);
  205.                 }
  206.                 else               
  207.                     process_up();
  208.                         }   
  209.             else if(evt == EVENT_OK_BUTTON_PUSHED)
  210.                         {
  211.                 btn_ok_pressed = 1;
  212.                 ellapsed = 0;
  213.                         }   
  214.             else if(evt == EVENT_MENU_BUTTON_PUSHED)
  215.                         {
  216.                 LOG((ROMCHAR)"menu\r\n");

  217.                 if(state == STATE_MENU)
  218.                     state_timeout = 1;  // change to idle
  219.                 else
  220.                 {
  221.                     MENU_init(&save_info.mem);
  222.                     state = STATE_MENU;
  223.                     state_timeout = MENU_TIMEOUT;
  224.                 }
  225.                         }
  226.             else if(evt == EVENT_OK_BUTTON_RELEASED)
  227.             {
  228. LOG((ROMCHAR)"OK released\r\n");
  229.                 btn_ok_pressed = 0;
  230.                 if(ellapsed < 250)
  231.                 {
  232.                     if(state == STATE_MENU)
  233.                     {
  234.                         if(MENU_run(MENU_OK))
  235.                         {
  236.                             save_info.enabled = 1;
  237.                             state_timeout = 400;
  238.                         }
  239.                         else
  240.                             state_timeout = MENU_TIMEOUT;
  241.                     }
  242.                     else               
  243.                     {
  244.                         switch(state)
  245.                         {
  246.                             case STATE_IDLE:
  247.                                 RDA5807M_Mute();
  248.                                 break;

  249.                             case STATE_MEMORY:
  250.                                 if(save_info.mem.memory[mem_idx] > 0)
  251.                                 {
  252.                                     RDA5807M_SetFrequency(save_info.mem.memory[mem_idx]);
  253.                                     state_timeout = 1;  // change to idle
  254.                                 }
  255.                                 break;
  256.                         }
  257.                     }
  258.                 }
  259.             }
  260.                 }
  261.         
  262.         if(read++ > 1)
  263.         {
  264.             read = 0;
  265.             RDA5807M_Read(&info);
  266.             update_lcd();
  267.         }
  268.         
  269.         if(save_info.mem_save_timeout > 0)
  270.         {
  271.             if(--save_info.mem_save_timeout <= 0)
  272.             {
  273.                 save_info.mem_save_timeout = 0;
  274. LOG((ROMCHAR)"SAVE DATA EEPROM\r\n");                     

  275. LOG((ROMCHAR)"chann %d\r\n", (int)save_info.mem.channel);

  276.             EEPROM_save_data(&save_info.mem);
  277.             }
  278.         }
  279.         
  280.         // Dont back to IDLE while pressing memory saving button
  281.         if(!btn_ok_pressed && state_timeout > 0)
  282.         {
  283.             if(--state_timeout <= 0)
  284.             {
  285. LOG((ROMCHAR)"IDLE\r\n");               
  286.                 state_timeout = 0;
  287.                 rds.ps_valid = 1;
  288.                 rds.rt_valid = 1;
  289.                 state = STATE_IDLE;
  290.             }
  291.         }
  292.         
  293.         ellapsed++;
  294.         if(btn_ok_pressed && ellapsed > 250)
  295.         {
  296.             save_info.mem.memory[mem_idx] = save_info.mem.channel;
  297.             state_timeout = 1;
  298.         }
  299.         }
  300. }

  301. static void process_up(void)
  302. {
  303.     switch(state)
  304.     {
  305.         case STATE_IDLE:
  306.             save_info.enabled = 1;
  307.             RDA5807M_SeekUp();
  308.             break;
  309.    
  310.         case STATE_VOLUME:
  311.             if(++save_info.mem.volume >= MAX_VOLUME)
  312.                 save_info.mem.volume = MAX_VOLUME;
  313.             state_timeout = BACK2IDLE_TIMEOUT;
  314.             RDA5807M_SetVolume(save_info.mem.volume);
  315.             break;
  316.             
  317.         case STATE_MEMORY:
  318.             if(++mem_idx >= MAX_CHANNEL_MEM)
  319.                 mem_idx = MAX_CHANNEL_MEM-1;
  320.             state_timeout = BACK2IDLE_TIMEOUT;
  321.             break;
  322.     }
  323. }

  324. static void process_dn(void)
  325. {
  326.     switch(state)
  327.     {
  328.         case STATE_IDLE:   
  329.             save_info.enabled = 1;
  330.             RDA5807M_SeekDown();
  331.             break;
  332.             
  333.         case STATE_VOLUME:
  334.             if(--save_info.mem.volume >= 0xFF)
  335.                 save_info.mem.volume = 0;
  336.             state_timeout = BACK2IDLE_TIMEOUT;
  337.             RDA5807M_SetVolume(save_info.mem.volume);
  338.             break;
  339.             
  340.         case STATE_MEMORY:
  341.             if(--mem_idx >= 0xFF)
  342.                 mem_idx = 0;
  343.             state_timeout = BACK2IDLE_TIMEOUT;
  344.             break;
  345.     }
  346. }

  347. static void update_volume(void)
  348. {
  349.     BYTE i = 0;
  350.    
  351.     strcpypgm2ram(LCDText[1], (ROMCHAR)"VOL ");
  352.     for(; i < save_info.mem.volume; ++i)
  353.         strcatpgm2ram(LCDText[1], (ROMCHAR)"\xFF");
  354. }

  355. static BYTE setup_memory(void)
  356. {
  357.     BYTE i = 0;
  358.     for(; i < MAX_CHANNEL_MEM; ++i)
  359.     {
  360.         if(save_info.mem.memory[i] > 0 && save_info.mem.memory[i] == info.freq)
  361.         {
  362.             return i;
  363.         }
  364.     }
  365.    
  366.     return 0xFF;
  367. }

  368. static void update_lcd(void)
  369. {
  370.     int num, dec;
  371.     char c[17] = {0};
  372.     BYTE memidx = 0;
  373.     char m[1] = {' '};
  374.     char m1[3] = {' ',' ', 0};
  375.    
  376.     static BYTE size = 0;
  377.     static BYTE pos  = 0;
  378.     static WORD ps   = 0;
  379.    
  380.     if(state < STATE_LAST_BASIC)
  381.     {
  382.         // Draw line 1
  383.         
  384.         if(state == STATE_MEMORY)
  385.         {
  386.             // Display current memory station
  387.             strncpypgm2ram(LCDText[0], (ROMCHAR)"       FM ---.- ", 16);
  388.             
  389.             if(save_info.mem.memory[mem_idx] > 0)
  390.             {
  391.                 num = save_info.mem.memory[mem_idx];
  392.                 dec = (int)floor(((save_info.mem.memory[mem_idx] - num) * 100)/10);
  393.                 if(dec % 2 == 0) dec += 1;
  394.                 sprintf(c, (ROMCHAR)"       FM %3d.%1d ", num, dec);
  395.                 strncpy(LCDText[0], c, 16);
  396.             }
  397.         }
  398.         else
  399.         {
  400.             // Display station currently tunned
  401.             strncpypgm2ram(LCDText[0], (ROMCHAR)" \xA5\xA5 SCANNING \xA5\xA5 ", 16);
  402.             
  403.             //if(info.fmtrue && info.tuneok)
  404.             //{
  405.                 num = info.freq;
  406.                 dec = (int)floor(((info.freq - num) * 100)/10);
  407.                 if(dec % 2 == 0) dec += 1;

  408.                 memidx = setup_memory();
  409.                 if(memidx != 0xFF) {
  410.                     itoa(memidx+1, m);
  411.                     m1[0] = 'M';
  412.                     m1[1] = m[0];
  413.                 }
  414.                 if(info.stereo)      
  415.                     sprintf(c, (ROMCHAR)"%1d %s   FM %3d.%1d\xA5", info.rssi, m1, num, dec);
  416.                 else
  417.                     sprintf(c, (ROMCHAR)"%1d %s   FM %3d.%1d ", info.rssi, m1, num, dec);

  418.                 strncpy(LCDText[0], c, 16);
  419.                
  420. if(info.fmtrue && info.tuneok)
  421. {
  422.                 // Start save timer
  423.                 if(save_info.enabled)
  424.                 {
  425.                     save_info.mem.channel = info.freq;
  426.                     save_info.mem_save_timeout = SAVE_TIMEOUT;
  427.                     save_info.enabled = 0;
  428.                 }
  429.             }
  430.         }
  431.         
  432.         switch(state)
  433.         {
  434.             case STATE_IDLE:
  435.             {
  436.                 if(!rds.use_rt && rds.ps_valid)
  437.                 {
  438.                     rds.ps_valid = 0;
  439.                     memset(LCDText[1], ' ', 16);
  440.                     strncpy(&LCDText[1][4], rds.ps_copy, 8);
  441.                 }
  442.                 else
  443.                 {
  444.                     if(rds.rt_valid)
  445.                     {
  446.                         rds.rt_valid = 0;
  447.                         memset(LCDText[1], ' ', 16);
  448.                         size = strlen(rds.rt_copy);
  449.                         pos = 0;
  450.                         ps = 0;
  451.                         strncpy(LCDText[1], rds.rt_copy, size > 16 ? 16 : size);
  452.                     }
  453.                     else
  454.                     {
  455.                         if(rds.use_rt && ps++ > 30)
  456.                         {
  457.                             ps = 0;
  458.                             if(size < 16)
  459.                                 strncpy(LCDText[1], rds.rt_copy, size > 16 ? 16 : size);
  460.                             else
  461.                                 strncpy(LCDText[1], &rds.rt_copy[pos++], (size - pos) > 16 ? 16 : size);
  462.                         }
  463.                     }
  464.                 }
  465.             }
  466.             break;

  467.             case STATE_VOLUME:
  468.                 update_volume();
  469.                 break;

  470.             case STATE_MEMORY:
  471.             {
  472.                 switch(mem_idx)
  473.                 {
  474.                     case 0:
  475.                         strncpypgm2ram(LCDText[1], (ROMCHAR)"MEM \x0A51 2 3 4 5 6", 16);
  476.                         break;
  477.                     case 1:
  478.                         strncpypgm2ram(LCDText[1], (ROMCHAR)"MEM 1 \x0A52 3 4 5 6", 16);
  479.                         break;
  480.                     case 2:
  481.                         strncpypgm2ram(LCDText[1], (ROMCHAR)"MEM 1 2 \x0A53 4 5 6", 16);
  482.                         break;
  483.                     case 3:
  484.                         strncpypgm2ram(LCDText[1], (ROMCHAR)"MEM 1 2 3 \x0A54 5 6", 16);
  485.                         break;
  486.                     case 4:
  487.                         strncpypgm2ram(LCDText[1], (ROMCHAR)"MEM 1 2 3 4 \x0A55 6", 16);
  488.                         break;
  489.                     case 5:
  490.                         strncpypgm2ram(LCDText[1], (ROMCHAR)"MEM 1 2 3 4 5 \x0A56", 16);
  491.                         break;
  492.                     default:
  493.                         LOG((ROMCHAR)"ERR %d\r\n", mem_idx);
  494.                         mem_idx = 0;
  495.                         break;
  496.                 }
  497.             }        
  498.             break;
  499.         }
  500.     }
  501.     else
  502.     {
  503.         MENU_draw();
  504.     }
  505.    
  506.     LCDUpdate();
  507. }
  508.    


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
xinpian101 发表于 2024-9-28 21:00 | 显示全部楼层
只要实现I2C读写一般就没太多问题了。所以学会I2C很重要啊。
coyoteie 发表于 2024-10-13 07:53 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

196

主题

3258

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部