[CW32F030系列] 【CW32F030CxTx StartKit开发板】+收音机制作思路

[复制链接]
1693|11
 楼主| gaoyang9992006 发表于 2024-6-14 23:27 | 显示全部楼层 |阅读模式
本帖最后由 gaoyang9992006 于 2024-6-14 23:28 编辑

1、设计思路与方案结构
一般DSP收音机集成芯片都是I2C接口,彩色显示屏一般都是SPI接口。按键使用GPIO+中断实现。
因此本次使用开发板显示收音机功能结构如下:
111111111111.jpg
通过开发板上的两个按键实现切换电台。
TFT彩屏与收音机模块采用杜邦线连接。
2、按键的实现
开发板上具备2个按键和2个LED灯珠,可以利用灯珠来学习按键,用于指示按键的状态。
按键的配置与中断可以参考标准库文件中提供的示例。
按键的使用需要配置按键所在的时钟使能,配置中断使能,设置IO模式为输入模式。

RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB, ENABLE);
另外注意到
        __RCC_GPIOB_CLK_ENABLE();
        __RCC_GPIOA_CLK_ENABLE();        

对应宏与上述函数式是一样的配置结果。

  1. void NVIC_Configuration(void)
  2. {
  3.   __disable_irq();
  4.         GPIOA_INTFLAG_CLR( 0xFFFF );    //clear GPIOA ALL INT FLAG
  5.         NVIC_EnableIRQ(GPIOA_IRQn);
  6.   __enable_irq();  
  7. }
  1. //LED引脚配置
  2.         GPIO_InitStructure.IT   = GPIO_IT_NONE;
  3.         GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  4.         GPIO_InitStructure.Pins = LED1_GPIO_PINS;
  5.         GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
  6.         GPIO_Init(LED1_GPIO_PORT,&GPIO_InitStructure);        
  7.         GPIO_WritePin(LED1_GPIO_PORT,LED1_GPIO_PINS,GPIO_Pin_SET);
  8.         
  9.         GPIO_InitStructure.Pins = LED2_GPIO_PINS;
  10.         GPIO_Init(LED2_GPIO_PORT,&GPIO_InitStructure);
  11.         GPIO_WritePin(LED2_GPIO_PORT,LED2_GPIO_PINS,GPIO_Pin_SET);
  12.         
  13.   //按键引脚配置
  14.         __RCC_GPIOA_CLK_ENABLE();
  15.         GPIO_InitStructure.IT   = GPIO_IT_FALLING;
  16.         GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  17.         GPIO_InitStructure.Pins = S1_GPIO_PINS;
  18.         GPIO_Init(S1_GPIO_PORT,&GPIO_InitStructure);        
  19.         GPIO_InitStructure.Pins = S2_GPIO_PINS;
  20.         GPIO_Init(S1_GPIO_PORT,&GPIO_InitStructure);
这样就可以完成按键的配置。

中断函数的实现是在一个interrupts_cw32f030.c文件中定义好了入口函数,只要完成函数体即可。
  1. void GPIOA_IRQHandler(void)
  2. {
  3.     /* USER CODE BEGIN */
  4.         if(REGBITS_GET(CW_GPIOA->ISR, GPIOx_ISR_PIN1_Msk) > 0)
  5.         {
  6.                 Key1_flag = 1;
  7.                 Key2_flag = 0;
  8.                 //清除CW_GPIO中断标志
  9.                 GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN1_Msk);
  10.         }
  11.         if(REGBITS_GET(CW_GPIOA->ISR, GPIOx_ISR_PIN2_Msk) > 0)
  12.         {
  13.                 Key1_flag = 0;
  14.                 Key2_flag = 1;
  15.                 //清除CW_GPIO中断标志
  16.                 GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN2_Msk);
  17.         }
  18.     /* USER CODE END */
  19. }
读取中断标志,判断操作,清除标志。

3、I2C的实现

I2C可以由软件实现,也可以由硬件实现
这里提供两种实现方式给大家参靠
  1. #include "IO_I2C.h"


  2. #if SOFTWARE_SPI_ENABLE

  3. void SDA_IO_DIR_OUTPUT(void)
  4. {
  5.         GPIO_InitTypeDef GPIO_InitStructure;
  6.         GPIO_InitStructure.IT   = GPIO_IT_NONE;
  7.         GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  8.         GPIO_InitStructure.Pins = SDA_IO_PIN;
  9.         GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
  10.         GPIO_Init(SDA_IO_PORT,&GPIO_InitStructure);        
  11. }

  12. void SDA_IO_DIR_INPUT(void)
  13. {
  14.         GPIO_InitTypeDef GPIO_InitStructure;
  15.         GPIO_InitStructure.IT   = GPIO_IT_NONE;
  16.         GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
  17.         GPIO_InitStructure.Pins = SDA_IO_PIN;
  18.         GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
  19.         GPIO_Init(SDA_IO_PORT,&GPIO_InitStructure);        
  20. }

  21. void SCL_IO_DIR_OUTPUT(void)
  22. {
  23.         GPIO_InitTypeDef GPIO_InitStructure;
  24.         GPIO_InitStructure.IT   = GPIO_IT_NONE;
  25.         GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  26.         GPIO_InitStructure.Pins = SCL_IO_PIN;
  27.         GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
  28.         GPIO_Init(SCL_IO_PORT,&GPIO_InitStructure);        
  29. }


  30. void i2cBeginTransaction()
  31. {

  32.         SDA_IO_DIR_OUTPUT();
  33.         SCL_IO_DIR_OUTPUT();
  34.         delay10us(1);        
  35.         SDA_IO_SET_HIGH();
  36.         SCL_IO_SET_HIGH();
  37.         SDA_IO_SET_LOW();
  38. }

  39. void i2cEndTransaction()
  40. {
  41.         SDA_IO_DIR_OUTPUT();
  42.         delay10us(1);
  43.         SDA_IO_SET_LOW();
  44.         SCL_IO_SET_HIGH();
  45.         delay10us(1);
  46.         SDA_IO_SET_HIGH();
  47. }

  48. void i2cAck()
  49. {
  50.         SDA_IO_DIR_OUTPUT();
  51.         delay10us(1);
  52.         SDA_IO_SET_LOW();
  53.         SCL_IO_SET_HIGH();
  54.   SCL_IO_SET_LOW();
  55. }

  56. void i2cNack()
  57. {
  58.         SDA_IO_DIR_OUTPUT();
  59.         delay10us(1);
  60.         SDA_IO_SET_HIGH();
  61.         SCL_IO_SET_HIGH();
  62.         SCL_IO_SET_LOW();
  63. }

  64. uint8_t i2cReceiveAck()
  65. {
  66.         uint8_t ack;
  67.         SDA_IO_DIR_INPUT();
  68.         delay10us(1);
  69.         SCL_IO_SET_HIGH();
  70.         ack = SDA_IO_GET_VALUE();
  71.         SCL_IO_SET_LOW();
  72.         return ack;
  73. }

  74. void i2cWriteByte(uint8_t data)
  75. {
  76.         SDA_IO_DIR_OUTPUT();
  77.         delay10us(1);
  78.         SCL_IO_SET_LOW();
  79.         for (int i = 0; i < 8; i++)
  80.         {
  81.                 if(0x80==(data & 0x80))
  82.                 {
  83.                         SDA_IO_SET_HIGH();
  84.                 }
  85.                 else
  86.                 {
  87.                         SDA_IO_SET_LOW();
  88.                 }
  89.                 SCL_IO_SET_HIGH();
  90.                 data = data << 1;
  91.                 SCL_IO_SET_LOW();
  92.         }
  93. }

  94. uint8_t i2cReadByte(void)
  95. {
  96.     uint8_t value = 0;

  97.     SDA_IO_DIR_INPUT();delay10us(1);

  98.     for (int i = 0; i < 8; i++)
  99.     {
  100.         SCL_IO_SET_HIGH();
  101.         value = value << 1;
  102.         if (SDA_IO_GET_VALUE())
  103.             value = value | 1;
  104.         SCL_IO_SET_LOW();
  105.     }
  106.     return value;
  107. }


  108. uint8_t KT_Byte_Read(uint8_t reg)
  109. {
  110.   uint8_t dat=0;
  111.   i2cBeginTransaction();
  112.   i2cWriteByte(0x6A);
  113.   i2cReceiveAck();
  114.   i2cWriteByte(reg);
  115.   i2cReceiveAck();
  116.   i2cBeginTransaction();
  117.   i2cWriteByte(0x6B);
  118.   i2cReceiveAck();
  119.   dat = i2cReadByte();
  120.   i2cNack();
  121.   i2cEndTransaction();
  122.   return dat;
  123. }

  124. void KT_Byte_Write(uint8_t reg,uint8_t dat)
  125. {
  126.   i2cBeginTransaction();
  127.   i2cWriteByte(0x6A);
  128.   i2cReceiveAck();
  129.   i2cWriteByte(reg);
  130.   i2cReceiveAck();
  131.   i2cWriteByte(dat);
  132.   i2cReceiveAck();
  133.   i2cEndTransaction();
  134. }
  135. void KT_I2C_Init(void)
  136. {
  137.         KT_I2C_SCL_CLK_ENABLE();
  138.         KT_I2C_SDA_CLK_ENABLE();
  139. }


  140. #else


  141. void KT_I2C_Init(void)
  142. {
  143.         KT_I2C_AFSCL;
  144.         KT_I2C_AFSDA;
  145.         
  146.   GPIO_InitTypeDef GPIO_InitStructure;
  147.   //I2C SCL SDA 复用
  148.   GPIO_InitStructure.Pins = KT_I2C_SCL_GPIO_PIN;
  149.   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  150.         GPIO_InitStructure.IT = GPIO_IT_NONE;
  151.         GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  152.   GPIO_Init(KT_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
  153.         
  154.   GPIO_InitStructure.Pins = KT_I2C_SDA_GPIO_PIN;
  155.   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  156.         GPIO_InitStructure.IT = GPIO_IT_NONE;
  157.         GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  158.   GPIO_Init(KT_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
  159.         
  160.   I2C_InitTypeDef I2C_InitStruct;

  161.   KT_I2C_ClkENx;

  162.         //I2C初始化
  163.         I2C_InitStruct.I2C_BaudEn = ENABLE;
  164.         I2C_InitStruct.I2C_Baud = 0x05;//1MHz=(48000000/(8*(5+1))
  165.         I2C_InitStruct.I2C_FLT = DISABLE;
  166.         I2C_InitStruct.I2C_AA = DISABLE;
  167.         
  168.         KT_I2C_DeInit;
  169.         I2C_Master_Init(KT_I2C,&I2C_InitStruct);//初始化模块
  170.         I2C_Cmd(KT_I2C,ENABLE);  //模块使能
  171. }




  172. uint8_t KT_Byte_Read(uint8_t u8Addr)
  173. {
  174.         uint8_t dat;
  175.         HAL_I2C_Mem_Read(KT_I2C,0x6A,u8Addr,&dat,1);
  176.         return dat;
  177. }

  178. void KT_Byte_Write(uint8_t reg,uint8_t dat)
  179. {
  180.         HAL_I2C_Mem_Write(KT_I2C,0x6A, reg, &dat, 1);
  181. }

  182. #endif
通过预编译中定义的宏来选择使用哪种。

4、SPI的实现
用于驱动TFT,推荐使用硬件实现。
应先对IO的复用功能进行选择,然后对IO进行配置,选择正确的IO模式,这里为推挽输出模式。最后对选择的SPI接口进行配置。
完成配置后并启用SPI接口,接下来就可以用相关写函数对TFT显示屏操作了。
  1. void SPI_Configuration(void)
  2. {
  3.         __RCC_GPIOA_CLK_ENABLE();
  4.         __RCC_GPIOB_CLK_ENABLE();
  5.         
  6.         PB13_AFx_SPI2SCK();
  7.         PB15_AFx_SPI2MOSI();        
  8.         
  9.         GPIO_InitTypeDef GPIO_InitStructure;
  10.         //推挽输出
  11.         GPIO_InitStructure.Pins = ST7735_CS_Pin;
  12.         GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  13.         GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  14.         GPIO_Init(ST7735_CS_GPIO_Port, &GPIO_InitStructure);        
  15.         
  16.         GPIO_InitStructure.Pins = ST7735_DC_Pin;
  17.         GPIO_Init(ST7735_DC_GPIO_Port, &GPIO_InitStructure);               
  18.         
  19.         GPIO_InitStructure.Pins = ST7735_RST_Pin;
  20.         GPIO_Init(ST7735_RST_GPIO_Port, &GPIO_InitStructure);        
  21.         
  22.         GPIO_InitStructure.Pins = ST7735_SCK_Pin;
  23.         GPIO_Init(ST7735_SCK_GPIO_Port, &GPIO_InitStructure);
  24.         
  25.         GPIO_InitStructure.Pins = ST7735_MOSI_Pin;
  26.         GPIO_Init(ST7735_MOSI_GPIO_Port, &GPIO_InitStructure);
  27.         
  28.         SPI_InitTypeDef SPI_InitStructure;
  29.         SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_TxOnly;         //单工只发
  30.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                         // 主机模式
  31.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                     // 帧数据长度为8bit
  32.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                           // 时钟空闲电平为高
  33.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                          // 第2个边沿采样
  34.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                             // 片选信号由SSI寄存器控制
  35.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;    // 波特率为PCLK的4分频
  36.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                    // 最高有效位 MSB 收发在前
  37.         SPI_InitStructure.SPI_Speed = SPI_Speed_Low;                          // 低速SPI
  38.         SPI_Init(ST7735_SPI, &SPI_InitStructure);
  39.         SPI_Cmd(ST7735_SPI, ENABLE);
  40. }

最后奉上完整的工程文件
游客,如果您要查看本帖隐藏内容请回复

演示视频看帖
https://bbs.21ic.com/icview-3382898-1-1.html

翅膀2009 发表于 2024-6-16 10:57 | 显示全部楼层
谢谢 工程文件
小夏天的大西瓜 发表于 2024-6-17 22:41 | 显示全部楼层
射频模块是自治的嘛?
 楼主| gaoyang9992006 发表于 2024-6-17 23:03 | 显示全部楼层

是的,就是KT0935做城模块,增加了耳机插座和外围电路。
huquanz711 发表于 2024-6-18 07:40 来自手机 | 显示全部楼层
用的集成芯片收音机
643757107 发表于 2024-6-20 21:33 | 显示全部楼层
如果多几个按键是不是还可以设置音量调节和波段切换。
jf101 发表于 2024-6-27 20:56 | 显示全部楼层
收音机集成芯片都是I2C接口,彩色显示屏一般都是SPI接口
szt1993 发表于 2024-6-29 15:58 | 显示全部楼层
收音机集成芯片现在都非常简单
lzm2008 发表于 2024-7-2 13:05 | 显示全部楼层
谢谢 工程文件
lzm2008 发表于 2024-7-2 13:05 | 显示全部楼层
AdaMaYun 发表于 2024-7-9 13:36 | 显示全部楼层
学习一下相关资料文档
xueqinglin 发表于 2024-7-19 16:17 | 显示全部楼层
谢谢 工程文件
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16403

帖子

222

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