基于STM32的外围系统设计


实现需求

在这里插入图片描述
在这里插入图片描述

前言

期末太忙,有空再写

总体框架

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 */
}

有些变量定义可能没截出,需要的话可以看着自己补一下定义,我会在忙完了以后补上。

总结

这是给大二本学期电设实验课做的综合设计,各个部分都比较好做,整合一下就可以成为初步的外围系统。工程文件已上传,可以在资源下载。
还有两个拓展需求,高频频率计和低频示波器,会慢慢补完,后续在新的文章更新。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值