一、新建工程略有不同的是程序的下载方法,需要装驱动。。。二、LED电路原理图:比赛板用的是stm32f103rb芯片,64管脚,LED与LCD同用了管脚PC8~PC15(对应LED1~LED8),所以增用了一个锁存器——M74HC573。在控制LED的时候,只需在输出对应电平后,给锁存器的LE(N—LE,对应PD2)管脚一个上升沿脉冲即可把对应的电平锁存到锁存器的输出端(Q1~Q8),从而控制LED。需要注意的是:1、LCD的操作会影响LED的亮灭,如LCD的行写会点亮所有的LED,需进行程序处理;2、对锁存器LE管脚的操作,给一个上升沿脉冲后应把对应的控制引脚(PD2)置低电平,以免LCD的操作影响LED的亮灭混乱。有关蜂鸣器的使用比较简单,在这里一起说明:比赛板的蜂鸣器连在PB4上,需注意的是Pb4管脚是JTAG调试接口之一,需要在程序中失能JTAG才可以使用Pb4管脚,如下语句:/*DisabletheSerialWireJtagDebugPortSWJ-DP*/GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);然而程序中用了这一句后,下次用JTAG下载程序时就下载不进去了,解决办法是:先按着开发板的RESET按键别松手,再点击keil中的下载,然后松手按键,程序就可正常下载进去了。三、USARTCT1117开发板的USART2与下载程序的USB方口集成在一起,使用时只需装好对应的驱动即可实现电脑与开发板的串口通信(部分串口调试工具可能搜不到串口)。比赛时对串口的使用方式可能性比较大的是,通过电脑发送指令控制stm32以执行相应操作,所以我结合LED编写了一个练习程序,使用串口发送指令控制LED亮灭,同时在LCD上显示最近一次所接收到的命令。串口的接收命令使用的是中断的方式,代码如下://配置串口2voidUSART_Configuration(void){GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure;NVIC_InitTypeDefNVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//PA2TxGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//PA3RxGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);USART_InitStructure.USART_BaudRate=9600;USART_InitStructure.USART_WordLength=USART_WordLength_8b;USART_InitStructure.USART_StopBits=USART_StopBits_1;USART_InitStructure.USART_Parity=USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init(USART2,&USART_InitStructure);USART_Cmd(USART2,ENABLE);//使能USART2/*ConfiguretheNVICPreemptionPriorityBits*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);/*EnabletheUSARTyInterrupt*/NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//使能接受中断}//中断服务函数voidUSART2_IRQHandler(void){if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET){/*Readonebytefromthereceivedataregister*/RxBuffer[RxCounter]=USART_ReceiveData(USART2);if(RxBuffer[RxCounter]=='x')//指令格式led2_onx,以’x’作为命令的结尾{rxflag=1;//接受到命令的标志RxCounter=0;}elseRxCounter++;if(RxBuffer[0]!='l')//此句避免接受命令混乱RxCounter=0;}USART_ClearITPendingBit(USART2,USART_IT_RXNE);//}//对于通过串口向电脑发送数据,采用printf()函数的重定向intfputc(intch,FILE*f){USART_SendData(USART2,(uint8_t)ch);while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);//delay_ms(10);returnch;}//库函数中有,复制即可使用主函数省略,其中主要是调用了一个对命令处理的函数,每次调用处理函数,先判断命令接受的标志位,若置为1,则对存放命令的数组内容进行判断,从而操作LED并显示当前的命令。Takecare:1、sprintf();函数的使用:字符串转换函数如sprintf(string,”%s%d%c”,”djkal”,a,buffer[5]);其中string可以为u8string[20];或者u8*string;类型;但是使用指针时程序总会卡死在这个函数中,调试时换为已指明大小的数组则避免了卡死问题;2、怀疑点:串口调试助手在发送数据到MCU时并不仅仅发送你输入的字符串,而有附加。3、通过电脑的串口助手或者超级终端发送指令控制开发板,指令最好自己定义格式。例如通过串口设置时间,可定义命令格式:A12:02:05B其中’A’,’B’分别为命令的起始位和停止位,注意电脑发送的是字符串(ASCII码),受到数据后需要转换成数字,如数字2和’2’相差48。若只是简单的控制不涉及数字,可以直接对字符进行识别即可。四、SysTick不涉及系统而言,主要用于较精准的延时,用最新的3.5库实现非常容易。首先调用SysTick_Config(SystemCoreClock/1000);其中SystemCoreClock是内核系统时钟频率,未做修改的话为72M(此函数并不关心此值大小),除以1000,则实现1ms中断一次。然后编写延时函数voiddelay_ms(u16nTime){TimingDelay=nTime;//TimingDelay设置为全局变量while(TimingDelay!=0);}中断服务函数voidSysTick_Handler(void){if(TimingDelay0)TimingDelay--;}具体代码实现过程:在SysTick_Config中配置了SysTick的中断频率,每次进入中断函数都把全局变量TimingDelay减一,而在延时函数中不断循环查询TimingDelay变量,直至TimingDelay变为0延时结束。有时需要考虑SysTick的中断优先级问题,如:如果EXTI的优先级高于Systick中断,则在按键消抖时会造成,在延时10ms消抖的过程中会不断被按键电路的毛刺影响而多次重新进入按键中断,而每次都会重新调用延时10ms,等到按键松手后再延时10ms已经不能读到对应按键的电平状态,不能实现消抖。解决此问题的方法很简单,就是更改SysTick_Config函数中对中断优先级的配置使它高于按键的优先级,具体实现见EXTI_KEY中的讲述。(写的比较啰嗦,大致道理还是比较简单)五、EXTI_KEY本次程序是在USART的基础之上,加上利用按键控制Led,实现按键与串口同时控制lED的亮灭。较为简单,直接结合原理图给程序。RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//切记打开复用时钟//K1.K2.K3.K4分别连接stm32上的Pa0,Pa8,Pb1,Pb2,配置为上拉输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOB,&GPIO_InitStructure);//key1的配置,其他同样配置即可GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//key1EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿中断EXTI_InitStructure.EXTI_LineCmd=ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);voidEXTI9_5_IRQHandler(void)//key2的中断函数,其他类似{if(EXTI_GetITStatus(EXTI_Line8)!=RESET){delay_ms(10);//延时消抖,此函数用得是Systick的中断