Direct Link
Direct Link
GPIO主要操作函数:
GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)
void HAL_GPIO_WritePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
设置IO输出低电平,点亮LED1:
HAL_GPIO_WritePin( LED1_GPIO_Port,LED1_Pin, (GPIO_PinState)0 ); //HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
通过GPIO检测按键状态
HAL_GPIO_ReadPin( KEY0_GPIO_Port,KEY0_Pin ); HAL_GPIO_ReadPin( KEY1_GPIO_Port,KEY1_Pin );
在CubeMX中配置好TIM,设定分频比和计数周期,自动Reload,中断Enable等。 在主函数启动定时器:
HAL_TIM_Base_Start_IT(&htim3);
添加中断处理函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == htim3.Instance) { /* Toggle LED */ HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); } }
在CubeMX中配置好UART,设定波特率,中断Enable等。
发送一个消息:
uint8_t aTxStartMessages[] = "\r\n****** USB Microphone ******\r\n"; HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)aTxStartMessages,sizeof(aTxStartMessages));
添加接收缓冲区:
uint8_t aRxBuffer[1];
启动接收中断:
HAL_UART_Receive_IT(&huart1,aRxBuffer,1);
添加中断回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { HAL_UART_Transmit(&huart1,aRxBuffer,1,100); HAL_UART_Receive_IT(&huart1,aRxBuffer,1); } }
在CubeMX中配置好USB和中间件USB_DEVICE。
在描述符参数内得为usb audio class,修改PID为0x5730(否则windows驱动会加载出错)
修改工程设置,将堆大小设为4K(Heap Size : 0x4000),栈大小设为1K(Stack Size: 0x1000)。
usbd_desc.c中包定义了设备名称,操作系统的设备管理中使用了这些设备名称,可根据具体设备修改名称。也可以在CubeMX的USB_DEVUCE中间件设置中修改。
#define USBD_VID 1155 #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "STMicroelectronics" #define USBD_PID_FS 0x5730 #define USBD_PRODUCT_STRING_FS "Xinsi Mixing Console" #define USBD_CONFIGURATION_STRING_FS "AUDIO Config" #define USBD_INTERFACE_STRING_FS "AUDIO Interface"
MX中配置完成,生成代码,编译加载到板上,连接USB电缆,Windows中就能发现硬件,安装驱动,可以见到设备安装成功。BUT,播放不了。
在CubeMX生成代码时,音频选择44.1k (宏USBD_AUDIO_FREQ),即44100,可以通过Windows上的Mute,播放操作,但尝试使用48k音频,会出现不能播放和静音不能控制的问题。
详细的配置过程可参考USB Audio设计与实现。
在CubeMX中配置好DAC的输出,选择DAC的触发源(Trigger),可选 Timer的触发输出事件,Disable波形生成模式。
配置Timer 6,Activate timer,设置Counter Period,选择 Triger Event Selection 为 Update Event
在Timer的中断回调函数中加入更新DAC值的代码。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { static uint16_t dac_value = 0; if (htim->Instance == htim6.Instance) { HAL_GPIO_TogglePin(TP0_GPIO_Port,TP0_Pin); // Toggle an GPIO HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dac_value); HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 4095-dac_value); dac_value++; if( dac_value >= 4096 ) { dac_value = 0; } } }
启动DAC和Timer。
HAL_DAC_Start(&hdac, DAC_CHANNEL_1); HAL_DAC_Start(&hdac, DAC_CHANNEL_2); HAL_TIM_Base_Start_IT(&htim6);
在系统时钟:72MHz, Timer周期1500(设置周期值Counter Period = 1499),Timer中断回调的调用周期是 72000/1500 = 48(kHz),GPIO输出方波周期是24kHz.