实现需求
前言
期末太忙,有空再写
总体框架
CUBEMX初始化
配置DMA
配置按键和LED
配置DAC
TIM6负责DAC
TIM10负责PWM
时钟树配置
关键代码
LED流水灯
可由按键调整启用LED数量,上下限1-10个
void FlowLED(int n){
for(int i=0;i!=n;i++){
switch(i){
case 0:
HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 1:
HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 2:
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 3:
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 4:
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 5:
HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 6:
HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 7:
HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 8:
HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 9:
HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED9_GPIO_Port,LED9_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
}
if(flow_flag)ShowStr(mov);
}
for(int i=n-1;i>-1;i--){
switch(i){
case 0:
HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_RESET);
HAL_Delay(100);
break;
case 1:
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 2:
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 3:
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 4:
HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 5:
HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 6:
HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED5_GPIO_Port,LED5_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 7:
HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED6_GPIO_Port,LED6_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 8:
HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED7_GPIO_Port,LED7_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
case 9:
HAL_GPIO_WritePin(LED9_GPIO_Port,LED9_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED8_GPIO_Port,LED8_Pin,GPIO_PIN_SET);
HAL_Delay(100);
break;
}
if(flow_flag)ShowStr(mov);
}
}
广告屏滚动字幕
void ShowStr(int t){
LCD_Clear(WHITE);
LCD_ShowString(t,40,500,24,24,"STUDENT NUMBER : 19081516"); //长度25*24=600
LCD_ShowString(t+50,70,500,24,24,"NAME : Li Tianyu"); //长度16*24=400
LCD_ShowString(t+53,100,200,24,24,"GROUP : Unknown"); //长度15*24=376
if(mov>=480)mov=0;
else mov+=15;
}
启用PWM
HAL_TIM_PWM_Start(&htim10,TIM_CHANNEL_1);
按键外部中断函数
此函数放于gpio.c下
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
extern int n;
int pulse;
extern int flow_flag;
extern int wave_flag;
extern int freq;
switch(GPIO_Pin){
case KEY0_Pin: //判断KEY0
delay_ms(10); //消抖
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==0 && HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin)==0){
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==1){ //减少灯
if(n>1)n--;
flow_flag=1;
//LCD_Clear(WHITE);
//sprintf((char*)led,"LED NUMBER: %02d",n);
//LCD_ShowString(100,40,500,24,24,led);
}
}
else if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==1){
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==1){
flow_flag=0;
STMFLASH_Read(FLASH_SAVE_ADDR,(u32 *)comp,SIZE);
sscanf((char*)comp,"%d",&pulse);
if(pulse>40) pulse-=42;
__HAL_TIM_SET_COMPARE(&htim10,TIM_CHANNEL_1,pulse); //降低占空比
sprintf((char*)comp,"%d",pulse);
STMFLASH_Write(FLASH_SAVE_ADDR,(u32 *)comp,SIZE);
sprintf((char*)comp,"PWM:%d %%",pulse*100/840);
LCD_Clear(WHITE);//清除半屏
LCD_ShowString(100,40,500,24,24,(u8 *)comp);
delay_ms(100);
}
}
else if(HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin)==1) {
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==1){ //提高频率 步长100
if(freq<10000)freq+=100;
int reload=84000000/256/freq-1;
__HAL_TIM_SET_AUTORELOAD(&htim6,reload);
sprintf((char *)fre,"Frequence: %d",84000000/256/(reload+1));
LCD_Clear(WHITE);
LCD_ShowString(100,40,500,24,24,(u8 *)fre);
}
}
break;
case KEY1_Pin: //判断KEY1
delay_ms(10); //消抖
if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==0 && HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin)==0){
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==1){ //增加灯
if(n<10)n++;
flow_flag=1;
//LCD_Clear(WHITE);
//sprintf((char*)led,"LED NUMBER: %02d",n);
//LCD_ShowString(100,40,500,24,24,led);
}
}
else if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)==1){
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==1){
flow_flag=0;
STMFLASH_Read(FLASH_SAVE_ADDR,(u32 *)comp,SIZE);
sscanf((char*)comp,"%d",&pulse);
if(pulse<800) pulse+=42;
__HAL_TIM_SET_COMPARE(&htim10,TIM_CHANNEL_1,pulse); //降低占空比
sprintf((char*)comp,"%d",pulse);
STMFLASH_Write(FLASH_SAVE_ADDR,(u32 *)comp,SIZE);
sprintf((char*)comp,"PWM:%d %%",pulse*100/840);
LCD_Clear(WHITE);//清屏
LCD_ShowString(100,40,500,24,24,(u8 *)comp);
delay_ms(100);
}
}
else if(HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin)==1) {
if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==1){ //降低频率 步长100
if(freq>800)freq-=100;
int reload=84000000/256/freq-1;
__HAL_TIM_SET_AUTORELOAD(&htim6,reload);
sprintf((char *)fre,"Frequence: %d",84000000/256/(reload+1));
LCD_Clear(WHITE);
LCD_ShowString(100,40,500,24,24,(u8 *)fre);
}
}
break;
case KEY2_Pin:
delay_ms(10);
LCD_Clear(WHITE);
LCD_ShowString(100,40,500,24,24,(char *)"Setting PWM!"); //KEY2对应pwm占空比设置
break;
case KEY3_Pin:
delay_ms(10);
flow_flag=0;
LCD_Clear(WHITE);
wave_flag=(wave_flag+1)%4;
switch(wave_flag){
case 0: //0对应方波
HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1, (uint32_t*)square_8bit, 256, DAC_ALIGN_8B_R);
LCD_ShowString(100,40,500,24,24,(char *)"Square Wave Generating!");
break;
case 1: //1对应三角波
HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1, (uint32_t*)triangle_8bit, 256, DAC_ALIGN_8B_R);
LCD_ShowString(100,40,500,24,24,(char *)"Triangle Wave Generating!");
break;
case 2: //2对应正弦波
HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1, (uint32_t*)sine_8bit, 256, DAC_ALIGN_8B_R);
LCD_ShowString(100,40,500,24,24,(char *)"Sine Wave Generating!");
break;
case 3: //3对应锯齿波
HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_1);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1, (uint32_t*)sawtooth_8bit, 256, DAC_ALIGN_8B_R);
LCD_ShowString(100,40,500,24,24,(char *)"Sawtooth Wave Generating!");
break;
}
}
}
主函数
int main(void)
{
/* USER CODE BEGIN 1 */
char comp[20];
int pulse=420-1;
u16 adcx;
extern uint32_t frequency_measure;
extern uint32_t cnt_TIM5;
extern uint8_t TIM5CH2_CAPTURE_STA;
float temp;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM10_Init();
MX_DAC_Init();
MX_TIM6_Init();
MX_TIM2_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
delay_init(168);
uart_init(115200); //初始化USART
LCD_Init(); //初始化LCD FSMC接口
HAL_TIM_Base_Start(&htim1); //定时中断记录周期数
// HAL_TIM_Base_Start(&htim5); //输入触发cnt+1
HAL_TIM_Base_Start(&htim6);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1, (uint32_t*)square_8bit, 256, DAC_ALIGN_8B_R);
//HAL_DMA_Start_IT(hdac.DMA_Handle1,(uint32_t)sine_8bit[256],0U,256);
LCD_Clear(WHITE);
POINT_COLOR=RED; //画笔颜色:红色
//sprintf((char*)comp,"%d",420);
//STMFLASH_Write(FLASH_SAVE_ADDR,(u32 *)comp,SIZE);
HAL_TIM_PWM_Start(&htim10,TIM_CHANNEL_1);
LCD_ShowString(100,40,500,24,24,"STUDENT NUMBER : 19081516");
LCD_ShowString(150,70,500,24,24,"NAME : Li Tianyu");
LCD_ShowString(153,100,200,24,24,"GROUP : Unknown");
STMFLASH_Read(FLASH_SAVE_ADDR,(u32 *)comp,SIZE); //读取flash
sscanf((char*)comp,"%d",&pulse);
__HAL_TIM_SET_COMPARE(&htim10,TIM_CHANNEL_1,pulse); //设置占空比
HAL_Delay(500); //亮灯
ShutLED();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
FlowLED(n);
mov+=5;
}
/* USER CODE END 3 */
}
有些变量定义可能没截出,需要的话可以看着自己补一下定义,我会在忙完了以后补上。
总结
这是给大二本学期电设实验课做的综合设计,各个部分都比较好做,整合一下就可以成为初步的外围系统。工程文件已上传,可以在资源下载。
还有两个拓展需求,高频频率计和低频示波器,会慢慢补完,后续在新的文章更新。