电设第一次作业
作业内容
- 实现LED流水灯
- 按键实现LED流水灯的开关,加速和监督
- 实现串口通信,将printf函数重定向到UART
静态变量
1 2 3
| int x=0; int t=0; int speed=500;
|
串口通信
原理图:

代码部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #include "stm32f10x.h" #include <stdio.h>
void Serial_Init(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO; GPIO.GPIO_Mode=GPIO_Mode_AF_PP; GPIO.GPIO_Pin=GPIO_Pin_9; GPIO.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO); USART_InitTypeDef USARTInit_Structure; USARTInit_Structure.USART_BaudRate=9600; USARTInit_Structure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USARTInit_Structure.USART_Mode=USART_Mode_Tx; USARTInit_Structure.USART_Parity=USART_Parity_No; USARTInit_Structure.USART_StopBits=USART_StopBits_1; USARTInit_Structure.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&USARTInit_Structure);
USART_Cmd(USART1,ENABLE);
}
void sendbyte(uint8_t t){ USART_SendData(USART1,t); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); } void sendarray(uint8_t *Array,uint16_t Length){
uint16_t i; for(i=0;i<Length;i++){ sendbyte(Array[i]); } } void sendstring(char *string){ uint8_t i; for(i=0;string[i]!='\0';i++){ sendbyte(string[i]); } } uint32_t Pow(uint32_t x,uint32_t y){ uint32_t result=1; while(y--){ result*=x; } return result; } void sendnumber(uint32_t number,uint8_t length){ uint8_t i; for(i=0;i<length;i++){ sendbyte(number/Pow(10,length-i-1)%10+0x30); } }
int fputc(int ch,FILE *f) {sendbyte(ch); return ch; }
|
LED流水灯的实现
1 2 3 4 5 6 7 8
| void ledInit(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO; GPIO.GPIO_Mode=0x10; GPIO.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5 ; GPIO.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO); }
|
1 2 3 4 5 6 7 8 9 10 11
| void led_flash(int i,int t){ switch(t){ case 0: GPIO_SetBits(GPIOA,GPIO_Pin_1);Delay_ms(i);GPIO_ResetBits(GPIOA,GPIO_Pin_1);break; case 1: GPIO_SetBits(GPIOA,GPIO_Pin_2);Delay_ms(i);GPIO_ResetBits(GPIOA,GPIO_Pin_2);break; case 2: GPIO_SetBits(GPIOA,GPIO_Pin_3);Delay_ms(i);GPIO_ResetBits(GPIOA,GPIO_Pin_3);break; case 3: GPIO_SetBits(GPIOA,GPIO_Pin_4);Delay_ms(i);GPIO_ResetBits(GPIOA,GPIO_Pin_4);break; case 4: GPIO_SetBits(GPIOA,GPIO_Pin_5);Delay_ms(i);GPIO_ResetBits(GPIOA,GPIO_Pin_5);break; } }
|
这里我采用外部中断的方式(在主循环一直扫描GPIO口,会导致cpu性能浪费甚至有可能会导致按键失灵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| void Exit_init(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIOb1; GPIOb1.GPIO_Mode=GPIO_Mode_IPU; GPIOb1.GPIO_Pin=GPIO_Pin_11; GPIOb1.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIOb1); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource11); EXTI_InitTypeDef EXTI_Init_Structure; EXTI_Init_Structure.EXTI_Line=EXTI_Line11; EXTI_Init_Structure.EXTI_LineCmd=ENABLE; EXTI_Init_Structure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_Init_Structure.EXTI_Trigger=EXTI_Trigger_Falling; EXTI_Init(&EXTI_Init_Structure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_Init_Structure; NVIC_Init_Structure.NVIC_IRQChannel=EXTI15_10_IRQn; NVIC_Init_Structure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority=0; NVIC_Init_Structure.NVIC_IRQChannelSubPriority=0; NVIC_Init(&NVIC_Init_Structure); } void speedup_Init(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIOb1; GPIOb1.GPIO_Mode=GPIO_Mode_IPU; GPIOb1.GPIO_Pin=GPIO_Pin_15; GPIOb1.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIOb1); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15); EXTI_InitTypeDef EXTI_Init_Structure; EXTI_Init_Structure.EXTI_Line=EXTI_Line15; EXTI_Init_Structure.EXTI_LineCmd=ENABLE; EXTI_Init_Structure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_Init_Structure.EXTI_Trigger=EXTI_Trigger_Falling; EXTI_Init(&EXTI_Init_Structure);
} void speeddown_Init(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIOb1; GPIOb1.GPIO_Mode=GPIO_Mode_IPU; GPIOb1.GPIO_Pin=GPIO_Pin_12; GPIOb1.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIOb1); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource12); EXTI_InitTypeDef EXTI_Init_Structure; EXTI_Init_Structure.EXTI_Line=EXTI_Line12; EXTI_Init_Structure.EXTI_LineCmd=ENABLE; EXTI_Init_Structure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_Init_Structure.EXTI_Trigger=EXTI_Trigger_Falling; EXTI_Init(&EXTI_Init_Structure);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| int main(){ ledInit(); Exit_init(); speedup_Init(); speeddown_Init(); while(1){ while(x){ printf("%d",x); led_flash(speed,t); t=(t+1)%5; } if(x==0) t=0; } } void EXTI15_10_IRQHandler(){ if(EXTI_GetITStatus(EXTI_Line11)==SET){ Easy_Delay_ms(15); while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)==0); Easy_Delay_ms(15); x=(x+1)%2; EXTI_ClearITPendingBit(EXTI_Line11); }else if(EXTI_GetITStatus(EXTI_Line15)==SET){ Easy_Delay_ms(15); while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)==0); Easy_Delay_ms(15); if(speed>100) speed-=100; EXTI_ClearITPendingBit(EXTI_Line15); }else if(EXTI_GetITStatus(EXTI_Line12)==SET){ Easy_Delay_ms(15); while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)==0); Easy_Delay_ms(15); if (speed<1000) speed+=100; EXTI_ClearITPendingBit(EXTI_Line12); } }
|