打印
[CW32F030系列]

【CW32F030CxTx StartKit开发板】+收音机制作思路

[复制链接]
242|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gaoyang9992006 于 2024-6-14 23:28 编辑

1、设计思路与方案结构
一般DSP收音机集成芯片都是I2C接口,彩色显示屏一般都是SPI接口。按键使用GPIO+中断实现。
因此本次使用开发板显示收音机功能结构如下:

通过开发板上的两个按键实现切换电台。
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();        

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

void NVIC_Configuration(void)
{
  __disable_irq();
        GPIOA_INTFLAG_CLR( 0xFFFF );    //clear GPIOA ALL INT FLAG
        NVIC_EnableIRQ(GPIOA_IRQn);
  __enable_irq();  
}
 //LED引脚配置
        GPIO_InitStructure.IT   = GPIO_IT_NONE;
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStructure.Pins = LED1_GPIO_PINS;
        GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
        GPIO_Init(LED1_GPIO_PORT,&GPIO_InitStructure);        
        GPIO_WritePin(LED1_GPIO_PORT,LED1_GPIO_PINS,GPIO_Pin_SET);
        
        GPIO_InitStructure.Pins = LED2_GPIO_PINS;
        GPIO_Init(LED2_GPIO_PORT,&GPIO_InitStructure);
        GPIO_WritePin(LED2_GPIO_PORT,LED2_GPIO_PINS,GPIO_Pin_SET);
        
  //按键引脚配置
        __RCC_GPIOA_CLK_ENABLE();
        GPIO_InitStructure.IT   = GPIO_IT_FALLING;
        GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
        GPIO_InitStructure.Pins = S1_GPIO_PINS;
        GPIO_Init(S1_GPIO_PORT,&GPIO_InitStructure);        
        GPIO_InitStructure.Pins = S2_GPIO_PINS;
        GPIO_Init(S1_GPIO_PORT,&GPIO_InitStructure);
这样就可以完成按键的配置。

中断函数的实现是在一个interrupts_cw32f030.c文件中定义好了入口函数,只要完成函数体即可。
void GPIOA_IRQHandler(void)
{
    /* USER CODE BEGIN */
        if(REGBITS_GET(CW_GPIOA->ISR, GPIOx_ISR_PIN1_Msk) > 0)
        {
                Key1_flag = 1;
                Key2_flag = 0;
                //清除CW_GPIO中断标志
                GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN1_Msk);
        }
        if(REGBITS_GET(CW_GPIOA->ISR, GPIOx_ISR_PIN2_Msk) > 0)
        {
                Key1_flag = 0;
                Key2_flag = 1;
                //清除CW_GPIO中断标志
                GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN2_Msk);
        }
    /* USER CODE END */
}
读取中断标志,判断操作,清除标志。

3、I2C的实现

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


#if SOFTWARE_SPI_ENABLE

void SDA_IO_DIR_OUTPUT(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.IT   = GPIO_IT_NONE;
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStructure.Pins = SDA_IO_PIN;
        GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
        GPIO_Init(SDA_IO_PORT,&GPIO_InitStructure);        
}

void SDA_IO_DIR_INPUT(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.IT   = GPIO_IT_NONE;
        GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
        GPIO_InitStructure.Pins = SDA_IO_PIN;
        GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
        GPIO_Init(SDA_IO_PORT,&GPIO_InitStructure);        
}

void SCL_IO_DIR_OUTPUT(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.IT   = GPIO_IT_NONE;
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStructure.Pins = SCL_IO_PIN;
        GPIO_InitStructure.Speed= GPIO_SPEED_HIGH;
        GPIO_Init(SCL_IO_PORT,&GPIO_InitStructure);        
}


void i2cBeginTransaction()
{

        SDA_IO_DIR_OUTPUT();
        SCL_IO_DIR_OUTPUT();
        delay10us(1);        
        SDA_IO_SET_HIGH();
        SCL_IO_SET_HIGH();
        SDA_IO_SET_LOW();
}

void i2cEndTransaction()
{
        SDA_IO_DIR_OUTPUT();
        delay10us(1);
        SDA_IO_SET_LOW();
        SCL_IO_SET_HIGH();
        delay10us(1);
        SDA_IO_SET_HIGH();
}

void i2cAck()
{
        SDA_IO_DIR_OUTPUT();
        delay10us(1);
        SDA_IO_SET_LOW();
        SCL_IO_SET_HIGH();
  SCL_IO_SET_LOW();
}

void i2cNack()
{
        SDA_IO_DIR_OUTPUT();
        delay10us(1);
        SDA_IO_SET_HIGH();
        SCL_IO_SET_HIGH();
        SCL_IO_SET_LOW();
}

uint8_t i2cReceiveAck()
{
        uint8_t ack;
        SDA_IO_DIR_INPUT();
        delay10us(1);
        SCL_IO_SET_HIGH();
        ack = SDA_IO_GET_VALUE();
        SCL_IO_SET_LOW();
        return ack;
}

void i2cWriteByte(uint8_t data)
{
        SDA_IO_DIR_OUTPUT();
        delay10us(1);
        SCL_IO_SET_LOW();
        for (int i = 0; i < 8; i++)
        {
                if(0x80==(data & 0x80))
                {
                        SDA_IO_SET_HIGH();
                }
                else
                {
                        SDA_IO_SET_LOW();
                }
                SCL_IO_SET_HIGH();
                data = data << 1;
                SCL_IO_SET_LOW();
        }
}

uint8_t i2cReadByte(void)
{
    uint8_t value = 0;

    SDA_IO_DIR_INPUT();delay10us(1);

    for (int i = 0; i < 8; i++)
    {
        SCL_IO_SET_HIGH();
        value = value << 1;
        if (SDA_IO_GET_VALUE())
            value = value | 1;
        SCL_IO_SET_LOW();
    }
    return value;
}


uint8_t KT_Byte_Read(uint8_t reg)
{
  uint8_t dat=0;
  i2cBeginTransaction();
  i2cWriteByte(0x6A);
  i2cReceiveAck();
  i2cWriteByte(reg);
  i2cReceiveAck();
  i2cBeginTransaction();
  i2cWriteByte(0x6B);
  i2cReceiveAck();
  dat = i2cReadByte();
  i2cNack();
  i2cEndTransaction();
  return dat;
}

void KT_Byte_Write(uint8_t reg,uint8_t dat)
{
  i2cBeginTransaction();
  i2cWriteByte(0x6A);
  i2cReceiveAck();
  i2cWriteByte(reg);
  i2cReceiveAck();
  i2cWriteByte(dat);
  i2cReceiveAck();
  i2cEndTransaction();
}
void KT_I2C_Init(void)
{
        KT_I2C_SCL_CLK_ENABLE();
        KT_I2C_SDA_CLK_ENABLE();
}


#else


void KT_I2C_Init(void)
{
        KT_I2C_AFSCL;
        KT_I2C_AFSDA;
        
  GPIO_InitTypeDef GPIO_InitStructure;
  //I2C SCL SDA 复用
  GPIO_InitStructure.Pins = KT_I2C_SCL_GPIO_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
        GPIO_InitStructure.IT = GPIO_IT_NONE;
        GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_Init(KT_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
        
  GPIO_InitStructure.Pins = KT_I2C_SDA_GPIO_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
        GPIO_InitStructure.IT = GPIO_IT_NONE;
        GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_Init(KT_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
        
  I2C_InitTypeDef I2C_InitStruct;

  KT_I2C_ClkENx;

        //I2C初始化
        I2C_InitStruct.I2C_BaudEn = ENABLE;
        I2C_InitStruct.I2C_Baud = 0x05;//1MHz=(48000000/(8*(5+1))
        I2C_InitStruct.I2C_FLT = DISABLE;
        I2C_InitStruct.I2C_AA = DISABLE;
        
        KT_I2C_DeInit;
        I2C_Master_Init(KT_I2C,&I2C_InitStruct);//初始化模块
        I2C_Cmd(KT_I2C,ENABLE);  //模块使能
}




uint8_t KT_Byte_Read(uint8_t u8Addr)
{
        uint8_t dat;
        HAL_I2C_Mem_Read(KT_I2C,0x6A,u8Addr,&dat,1);
        return dat;
}

void KT_Byte_Write(uint8_t reg,uint8_t dat)
{
        HAL_I2C_Mem_Write(KT_I2C,0x6A, reg, &dat, 1);
}

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

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

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

演示视频看帖
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做城模块,增加了耳机插座和外围电路。

使用特权

评论回复
5
huquanz711| | 2024-6-18 07:40 | 只看该作者
用的集成芯片收音机

使用特权

评论回复
6
643757107| | 2024-6-20 21:33 | 只看该作者
如果多几个按键是不是还可以设置音量调节和波段切换。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:西安公路研究院南京院
简介:主要工作从事监控网络与通信网络设计,以及从事基于嵌入式的通信与控制设备研发。擅长单片机嵌入式系统物联网设备开发,音频功放电路开发。

1905

主题

15675

帖子

200

粉丝