STM实验程序代码
stm32单片机小时计时程序代码

stm32单片机小时计时程序代码STM32单片机小时计时程序代码一、引言在现代社会中,时间是非常重要的一个因素。
而在很多应用中,对时间的计时需求也是非常常见的。
STM32单片机是一种常用的嵌入式微控制器,具有强大的计时功能。
本文将介绍如何使用STM32单片机编写一个小时计时程序代码。
二、程序设计思路本程序的设计思路是通过定时器中断来实现小时计时功能。
具体步骤如下:1. 初始化STM32单片机的定时器和相关寄存器。
2. 设置定时器的计时周期,使其每隔一定时间触发一次中断。
3. 在中断服务函数中,每次触发中断时进行计时器的累加操作。
4. 根据累加的值判断是否达到1小时,如果达到,则进行相关处理。
三、程序代码实现以下是一个简单的示例代码,演示了如何使用STM32单片机实现小时计时功能:```c#include "stm32f10x.h"#include "stm32f10x_tim.h"volatile uint32_t hour_count = 0;void TIM2_IRQHandler(void){if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){hour_count++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}}int main(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeBaseStructure.TIM_Period = 3600000 - 1; // 设置定时周期为1小时TIM_TimeBaseStructure.TIM_Prescaler = 7199; // 设置定时器预分频值,使定时器时钟为10kHzTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);TIM_Cmd(TIM2, ENABLE);while (1){if (hour_count > 0){// 在这里进行每小时的处理操作,例如打印计时结果等// 重置计时器hour_count = 0;}}}```四、代码解析1. 首先,我们需要包含相关的头文件,其中"stm32f10x.h"是STM32单片机的头文件,"stm32f10x_tim.h"是定时器相关的头文件。
STM32综合实验

编号:《嵌入式原理及应用》实验报告实验项目:综合实验专业:电子信息工程学号:学生姓名:指导教师:时间批次:第13周星期7第4大节第4批次2020 年5月24日一、源代码详细注释#include "stm32f10x.h"#define Key1 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)#define Key2 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)unsigned char LCDBuffer[10]={""};unsigned char LCDBuffer2[12]={" LISONGLIN"};int msCounter=0;void SysTick_Handler(void)//--- systick中断函数---{msCounter++;}void DelaymS(int t){ int ta,tb;ta=tb=msCounter;while((tb-ta)<t){tb=msCounter;}}void Init_LCD_Pin(void)//初始化屏幕引脚、按键引脚、虚拟终端引脚{ GPIO_InitTypeDef MyGPIO;//定义结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ GPIOA,ENABLE); //使能PC,PB端口时钟MyGPIO.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_13| GPIO_Pin_14 ;MyGPIO.GPIO_Speed=GPIO_Speed_50MHz; // I/O口频率50MhzMyGPIO.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &MyGPIO); //使用MyGPIO参数初始化GPIOBMyGPIO.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2 ; //选择引脚MyGPIO.GPIO_Speed=GPIO_Speed_50MHz; I/O口频率50MhzMyGPIO.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出GPIO_Init(GPIOA,&MyGPIO); //使用MyGPIO参数初始化GPIOAMyGPIO.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_2 ; //选择引脚MyGPIO.GPIO_Speed=GPIO_Speed_50MHz; I/O口频率50MhzMyGPIO.GPIO_Mode=GPIO_Mode_IN_FLOATING; //配置IO口为浮空输入模式GPIO_Init(GPIOC,&MyGPIO); //使用MyGPIO参数初始化GPIOC}#define RS_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_2) //设置GPIOB.2输出0,等同PBout(2)=0#define RS_SET GPIO_SetBits(GPIOA,GPIO_Pin_2) //设置GPIOA.2输出1,等同PAout(2)=1#define EN_CLR GPIO_ResetBits(GPIOA,GPIO_Pin_1)#define EN_SET GPIO_SetBits(GPIOA,GPIO_Pin_1)//LCD1602写指令函数void LCD_Write_Com(unsigned char com)//写指令{ int i;for(i=0; i<1000; i++);GPIO_Write(GPIOB,(int)(com & 0x03)<<1 |(com&0x0c)<<2 |(com & 0x30)<<4 |(com & 0xc0)<<7);RS_CLR;EN_SET;EN_CLR;}//LCD1602写数据函数void LCD_Write_Data(unsigned char Data)//写数据{ int i;for(i=0; i<1000; i++);GPIO_Write(GPIOB,(int)(Data & 0x03)<<1 |(Data & 0x0c)<<2 |(Data & 0x30)<<4 |(Data & 0xc0)<<7); RS_SET;EN_SET;EN_CLR;}void LCD_Init (void) //LCD1602初始化函数{ int i;LCD_Write_Com(0x38);//设置成8位驱动,2行5x7点for(i=0;i<100000;i++);LCD_Write_Com(0x38);for(i=0; i<100000; i++);LCD_Write_Com(0x38);for(i=0;i<100000;i++);LCD_Write_Com(0x38);关闭光标LCD_Write_Com(0x08);//显示模式LCD_Write_Com(0x01);//不显示光标LCD_Write_Com(0x06);//清除显示for(i=0;i<100000;i++);LCD_Write_Com(0x0C);}void LCD_Write_Char(char x, char y, char Data)//显示字符{ if(0==y)LCD_Write_Com(0x80 + x);elseLCD_Write_Com(0xC0+x);LCD_Write_Data(Data);}long KeyCnt=0;void keyscan(){ unsigned char i;if(Key1==0){ DelaymS(10);if(Key1==0){ LCD_Write_Com(0x38);for(i=0;i<12;i++)LCD_Write_Char(2+i,0,LCDBuffer2[i]);}DelaymS(10);//时延}if(Key2==0){ DelaymS(10);if(Key2==0){KeyCnt++;}DelaymS(10);}if(KeyCnt==9999)KeyCnt=0;//返回}unsigned char LCDBuffer1[]={" KeyCnt=0000"};//虚拟终端初始化显示int main(void)//主程序{ unsigned char i=0;if(SysTick_Config(SystemCoreClock/1000)){while(1);}Init_LCD_Pin();LCD_Init();for(i=0;i<14;i++)LCD_Write_Char(i,1,LCDBuffer1[i]);for(i=0;i<10;i++)LCD_Write_Char(3+i,0,LCDBuffer[i]);while(1){ keyscan();if(KeyCnt/1000 >0)LCD_Write_Char(10,1,KeyCnt/1000 + '0');else LCD_Write_Char(10,1,'0');if((KeyCnt%1000)/100 >0)LCD_Write_Char(11,1,(KeyCnt%1000 /100) + '0');else LCD_Write_Char(11,1,'0');if((KeyCnt%100)/10 >0)LCD_Write_Char(12,1,(KeyCnt%100)/10 + '0');else LCD_Write_Char(12,1,'0');if(KeyCnt%10 >0)LCD_Write_Char(13,1,KeyCnt%10 + '0');else LCD_Write_Char(13,1,'0');}}二、程序流程图三、程序运行过程描述先定义中断函数和延时函数;后将屏幕引脚和按键引脚初始化,定义引脚功能,声明结构体,输出模式等参数等,定义虚拟终端输出引脚;再定义存储数据的寄存器,在寄存器中写入指令和数据;定义LED显示函数,信号初始化等,然后屏幕显示字符。
基于stm32控制的步进电机程序代码

基于stm32控制的步进电机程序代码一、前言步进电机是一种常见的电机类型,其控制方式也有很多种。
在本文中,我们将介绍如何使用STM32控制步进电机。
二、硬件准备在开始编写程序之前,我们需要准备以下硬件:1. STM32单片机开发板2. 步进电机驱动板3. 步进电机4. 电源三、步进电机驱动原理步进电机驱动原理是通过不同的脉冲信号来控制步进电机转动。
其中,每个脉冲信号代表着一个步进角度,而不同的脉冲序列则可以实现不同的转速和方向。
四、STM32控制步进电机程序代码以下是基于STM32控制步进电机的程序代码:```c#include "stm32f10x.h"#define CLK_PORT GPIOA#define CLK_PIN GPIO_Pin_0#define DIR_PORT GPIOA#define DIR_PIN GPIO_Pin_1void delay_us(uint16_t us){uint16_t i;while(us--){i = 10;while(i--);}void step(uint8_t dir){if(dir == 0)GPIO_ResetBits(DIR_PORT, DIR_PIN);elseGPIO_SetBits(DIR_PORT, DIR_PIN);for(int i=0; i<200; i++){GPIO_SetBits(CLK_PORT, CLK_PIN);delay_us(2);GPIO_ResetBits(CLK_PORT, CLK_PIN);delay_us(2);}}int main(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin = CLK_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(CLK_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = DIR_PIN;GPIO_Init(DIR_PORT, &GPIO_InitStructure);while(1){step(0);delay_us(1000);step(1);delay_us(1000);}}```五、代码解析1. 定义了CLK_PORT和CLK_PIN,用于控制步进电机的脉冲信号。
stm32单片机抢答器程序代码v5

stm32单片机抢答器程序代码v5STM32单片机抢答器程序代码v5介绍STM32是一种高度集成的32位微控制器,具有高性能、低功耗、易于开发等优点。
抢答器是一种常见的教学工具,可以用于测试学生的反应速度和知识水平。
本文将介绍STM32单片机抢答器程序代码v5。
硬件配置本程序使用STM32F103C8T6单片机,外部晶振为8MHz。
按键使用GPIO口连接,共有4个按键,分别对应A、B、C、D四个选项。
LCD显示屏使用SPI接口连接,显示题目和计时。
软件设计本程序采用Keil uVision 5开发环境进行编程,使用ST公司提供的标准库函数进行驱动。
主要功能包括:初始化系统、初始化LCD显示屏、初始化按键、随机生成题目、计时并更新LCD显示屏等。
1. 初始化系统在main函数中调用SystemInit函数进行系统初始化。
该函数由ST 公司提供,在startup_stm32f103xe.s文件中定义。
2. 初始化LCD显示屏在main函数中调用LCD_Init函数进行LCD显示屏初始化。
该函数通过SPI接口向LCD发送指令和数据,并设置相关参数。
3. 初始化按键在main函数中调用Key_Init函数进行按键初始化。
该函数通过GPIO 口读取按键状态,并设置相关参数。
4. 随机生成题目在main函数中调用Generate_Question函数生成随机题目。
该函数使用rand函数生成两个随机数,并根据随机数确定运算符和答案。
5. 计时并更新LCD显示屏在main函数中调用Timer_Init函数进行计时器初始化,并在while循环中调用Timer_Update函数更新计时器。
同时,在while循环中调用LCD_Display函数更新LCD显示屏,包括题目、选项、答案和计时。
程序代码下面是完整的程序代码:```#include "stm32f10x.h"#include "lcd.h"#include "key.h"#include <stdlib.h>void SystemInit(void);void LCD_Init(void);void Key_Init(void);void Generate_Question(void);void Timer_Init(void);void Timer_Update(void);void LCD_Display(void);int question1, question2, answer;char operator;int time_count = 0;int main(){SystemInit();LCD_Init();Key_Init();Generate_Question();Timer_Init();while (1){Timer_Update();LCD_Display();if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == 0) // A {if (answer == 1){GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // LED offGenerate_Question();}else{GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET); // LED off}}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) == 0) // B {if (answer == 2){GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // LED offGenerate_Question();}else{GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET); // LED off}}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0) // C {if (answer == 3){GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // LED offGenerate_Question();}else{GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET); // LED off}}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15) == 0) // D {if (answer == 4){GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // LED offGenerate_Question();}else{GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET); // LED onDelay_ms(500);GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET); // LED off}}}}void Generate_Question(void){question1 = rand() % 10 + 1;question2 = rand() % 10 + 1;switch (rand() % 4){case 0:operator = '+';answer = question1 + question2;break;case 1:operator = '-';answer = question1 - question2;break;case 2:operator = '*';answer = question1 * question2;break;case 3:operator = '/';answer = question1 / question2;break;}}void Timer_Init(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_TimeBaseStructure.TIM_Period = 999; // 计数周期为1000,即每秒计数1000次TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / 1000000 - 1; // 分频系数为72,即计数频率为72MHz/72=1MHzTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 不分频TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up; // 向上计数TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);}void Timer_Update(void){if (TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) == SET) // 计时器溢出{TIM_ClearFlag(TIM3, TIM_FLAG_Update);time_count++;}}void LCD_Display(void){char str[16];sprintf(str, "%d%c%d=?", question1, operator, question2); LCD_ShowString(0, 0, str);LCD_ShowString(0, 1, "A: B: C: D:");sprintf(str, "%02d:%02d", time_count / 60, time_count % 60);LCD_ShowString(10, 2, str);}```总结本文介绍了STM32单片机抢答器程序代码v5,包括硬件配置和软件设计。
STM32模拟IIC读写24C02程序代码

STM32模拟IIC读写24C02程序代码STM32 模拟IIC读写24C02程序代码最近用到STM32F103V来读写A T24C02 EEPROM 于是从原来51单片机的程序代码的基础上修改了下,移植到了STM32,测试工作正常。
引脚定义和配置:#define SCL GPIO_Pin_6 //24C02 SCL#define SDA GPIO_Pin_7 //24C02 SDAvoid GPIO_Configuration(void){RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOE, ENABLE);GPIO_InitStructure.GPIO_Pin = SCL; //24C02 SC LGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);}void AT24C02_SDA_IO_SET(unsigned char io_set) //SDA引脚输入输出设置{if(io_set==0){GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);else if(io_set==1){GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入GPIO_Init(GPIOB, &GPIO_InitStructure);}else{;}}////////////////////////////////////主程序////////////////////////////////////////////////////////////////////// ////////int main(void){ uchar i;uchar data_24c02;RCC_Configuration(); //时钟配置GPIO_Configuration();//GPIO配置USARTx_configuration();//串口配置WIN24C02_init();delayms(5000);//延时for(i=0;i<20;i++) //写EEPROM数据{ WIN24C02_write(0x00+i,i);delayms(100);}//存数据到EEPROMdelayms(1000);//延时while(1)//串口3发送读取的EEPROM的数据{for(i=0;i<20;i++){ data_24c02=WIN24C02_read(0x00+i);//读取24C02数据USART_SendData(USART3 ,data_24c02);while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);}delayms(5000);//延时}/////////////////////////////////////////////////////////////////// //////////////////////////////////////////////WIN_24C02.H头文件/**********************中文版本*******************************//*****功能描述: STM32 24C02 读写程序*****//*****作者: 郑文(ClimberWin) *****//*****编写日期: 2013年1月21日*****//*****版本信息: V1.0 *****//*****修改日期: *****//*************************************************************/ #ifndef __WIN24C02_H__#define __WIN24C02_H__#include"STM32_Config.h"#define uchar unsigned char#define uint unsigned intuchar WIN24C02_read(uchar address); //从24c02的地址address中读取一个字节数据void WIN24C02_write(uchar address,uchar info); //向24c02的address地址中写入一字节数据infovoid WIN24C02_init(); //24c02初始化子程序void delay_nop(void);void delay2(uint x);void start();void stop();void writex(uchar j);uchar readx();void clock();void delay2(uint x){uint i;for(i=0;i<x;i++);< p="">}void delay_nop(void){uint8_t i=10; //i=10延时1.5us//这里可以优化速度,经测试最低到5还能写入while(i--);}void WIN24C02_init(){//SCL=1;GPIO_SetBits(GPIOB,SCL);delay_nop();//SDA=1;GPIO_SetBits(GPIOB,SDA);delay_nop();}void start(){//SDA=1;GPIO_SetBits(GPIOB,SDA);delay_nop();//SCL=1;GPIO_SetBits(GPIOB,SCL); delay_nop();//SDA=0;GPIO_ResetBits(GPIOB, SDA); delay_nop();//SCL=0;GPIO_ResetBits(GPIOB, SCL); delay_nop();}void stop(){//SDA=0;GPIO_ResetBits(GPIOB, SDA); delay_nop();//SCL=1;GPIO_SetBits(GPIOB,SCL); delay_nop();//SDA=1;GPIO_SetBits(GPIOB,SDA); delay_nop();}void writex(uchar j){uchar i,temp,temp1;temp=j;//A T24C02_SDA_IO_SET(0); for (i=0;i<8;i++){temp1=temp & 0x80;temp=temp<<1;//SCL=0;GPIO_ResetBits(GPIOB, SCL);delay_nop();//SDA=CY;if(temp1==0x80){GPIO_SetBits(GPIOB, SDA);} else {GPIO_ResetBits(GPIOB, SDA);} delay_nop(); // SCL=1;GPIO_SetBits(GPIOB,SCL);delay_nop();}//A T24C02_SDA_IO_SET(0);//SCL=0;GPIO_ResetBits(GPIOB, SCL);delay_nop();//SDA=1;GPIO_SetBits(GPIOB,SDA);delay_nop();}uchar readx(){uchar i,j,k=0;//SCL=0;GPIO_ResetBits(GPIOB, SCL);delay_nop();//SDA=1;GPIO_SetBits(GPIOB,SDA);AT24C02_SDA_IO_SET(1);for (i=0;i<8;i++){delay_nop();//SCL=1;GPIO_SetBits(GPIOB,SCL);delay_nop();//if (SDA==1) j=1;if( GPIO_ReadInputDataBit(GPIOB,SDA)==1 ) {j=1;}else{j=0;}k=(k<<1)|j;//SCL=0;GPIO_ResetBits(GPIOB, SCL);}AT24C02_SDA_IO_SET(0);delay_nop();return(k);}{uint i=0;AT24C02_SDA_IO_SET(1);//SCL=1;GPIO_SetBits(GPIOB,SCL);delay_nop();while((GPIO_ReadInputDataBit(GPIOB,SDA)==1)&&(i<5000))i++;//SCL=0;GPIO_ResetBits(GPIOB, SCL);delay_nop();AT24C02_SDA_IO_SET(0);}uchar WIN24C02_read(uchar address){uchar i;start();writex(0xa0);clock();writex(address);clock();start();writex(0xa1);clock();i=readx();stop();//delay2(10);delay2(50);return(i);}void WIN24C02_write(uchar address,uchar info) {start();writex(0xa0);clock();writex(address);writex(info);clock();stop();//delay2(50);delay2(250); }#endif</x;i++);<>。
STM8的C语言编程-UART应用

STM8的C语言编程(8)-- UART应用串口通讯也是单片机应用中经常要用到,今天的实验就是利用STM8的UART资源,来进行串口通讯的实验。
实验程序的功能是以中断方式接收串口数据,然后将接收到的数据以查询方式发送到串口。
程序代码如下,首先要对STM8的UART进行初始化,初始化时要注意的是波特率寄存器的设置,当求出一个波特率的分频系数(一个16位的数)后,要将高4位和低4位写到BRR2中,而将中间的8位写到BRR1中,并且必须是先写BRR2,再写BRR1。
同样也是利用ST的开发工具,生成一个C语言的框架,然后修改其中的main.c,同时由于需要用到中断服务,因此还要修改stm8_interrupt_vector.c。
修改后,编译连接,然后下载到开发板上,再做一根与PC机相连的线,把开发板的串口与PC机的串口连接起来,注意,2、3脚要交叉。
在PC机上运行超级终端,设置波特率为9600,然后每按下一个按键,屏幕上就显示对应的字符。
修改后的main.c和stm8_interrupt_vector.c如下:// 程序描述:初始化UART,以中断方式接收字符,以查询方式发送// UART通讯参数:9600bps,8位数据,1位停止位,无校验#include "STM8S207C_S.h"// 函数功能:初始化UART// 输入参数:无// 输出参数:无// 返回值:无// 备注:无void UART3_Init(void){LINUART_CR2 = 0; // 禁止UART发送和接收LINUART_CR1 = 0; // b5 = 0,允许UART// b2 = 0,禁止校验LINUART_CR3 = 0; // b5,b4 = 00,1个停止位// 设置波特率,必须注意以下几点://(1) 必须先写BRR2//(2) BRR1存放的是分频系数的第11位到第4位,//(3) BRR2存放的是分频系数的第15位到第12位,和第3位到第0位// 例如对于波特率位9600时,分频系数=2000000/9600=208// 对应的十六进制数为00D0,BBR1=0D,BBR2=00LINUART_BRR2 = 0;LINUART_BRR1 = 0x0d; // 实际的波特率分频系数为00D0(208) // 对应的波特率为2000000/208=9600 LINUART_CR2 = 0x2C; // b3 = 1,允许发送// b2 = 1,允许接收// b5 = 1,允许产生接收中断}// 函数功能:从UART3发送一个字符// 输入参数:ch -- 要发送的字符// 输出参数:无// 返回值:无// 备注:无void UART3_SendChar(unsigned char ch){while((LINUART_SR & 0x80) == 0x00); // 若发送寄存器不空,则等待 LINUART_DR = ch; // 将要发送的字符送到数据寄存器}main(){// 首先初始化UART3UART3_Init();_asm("rim"); // 允许CPU全局中断while(1) // 进入无限循环{}}// 函数功能:UART3的接收中断服务程序// 输入参数:无// 输出参数:无// 返回值:无@far @interrupt void UART3_Recv_IRQHandler (void){unsigned char ch;ch = LINUART_DR; // 读入接收到的字符 UART3_SendChar(ch); // 将字符发送出去}/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void @far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};@far @interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction */return;}extern void _stext(); /* startup routine */extern @far @interrupt void UART3_Recv_IRQHandler();struct interrupt_vector const _vectab[] ={0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, NonHandledInterrupt}, /* irq13 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, NonHandledInterrupt}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, UART3_Recv_IRQHandler}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */};2010-8-6程序备份/* MAIN.C file** Copyright (c) 2002-2005 STMicroelectronics*/#include "STM8S103f3p.h"/////////////////////////////////////////void Init_UART1(void){UART1_CR1=0x00;UART1_CR2=0x00;UART1_CR3=0x00;// 设置波特率,必须注意以下几点:// (1) 必须先写BRR2// (2) BRR1存放的是分频系数的第11位到第4位,// (3) BRR2存放的是分频系数的第15位到第12位,和第3位// 到第0位// 例如对于波特率位9600时,分频系数=2000000/9600=208// 对应的十六进制数为00D0,BBR1=0D,BBR2=00UART1_BRR2=0x00;UART1_BRR1=0x0d;UART1_CR2=0x2c;//允许接收,发送,开接收中断}///////////////////////////////////////////void UART1_sendchar(unsigned char c){while((UART1_SR&0x80)==0x00);UART1_DR=c;}////////////////IO初始化////////////////////void init_gpio(void){//将pb5设置成推挽输出PB_DDR = 0x20; //数据方向PB_CR1 = 0x20; // 上拉、悬空PB_CR2 = 0x00;}/////////////////////////////////////////////main(){unsigned char i=0;init_gpio();Init_UART1();_asm("rim");//开中断,sim为关中断while (1);}//将收到的数据再发送出去@far @interrupt void UART1_Recv_IRQHandler (void) {unsigned char ch;ch=UART1_DR;UART1_sendchar(ch);PB_ODR^=0x20;return;}/*/////////////////////////////////////串口发送程序///////////////////////////////////////#include "STM8S103f3p.h"void delay(unsigned int ms){unsigned char i;while(ms != 0){for(i=0;i<250;i++){}for(i=0;i<75;i++){}ms--;}}/////////////uart初始化///////////////////void init_uart1(void){UART1_CR1=0x00;UART1_CR2=0x00;UART1_CR3=0x00;// 设置波特率,必须注意以下几点:// (1) 必须先写BRR2// (2) BRR1存放的是分频系数的第11位到第4位,// (3) BRR2存放的是分频系数的第15位到第12位,和第3位// 到第0位// 例如对于波特率位9600时,分频系数=2000000/9600=208// 对应的十六进制数为00D0,BBR1=0D,BBR2=00UART1_BRR2=0x00;UART1_BRR1=0x0d;UART1_CR2=0x2c; //允许接收,发送,开接收中断}//////////////uart发送程序//////////////////////void uart1_sendchar(unsigned char c){while((UART1_SR & 0x80)==0x00);UART1_DR=c;}//////////////初始化A/D模块/////////////////////void init_ad(void){ADC_CR2 = 0x00; // A/D结果数据左对齐ADC_CR1 = 0x00; // ADC时钟=主时钟/2=1MHZ// ADC转换模式=单次// 禁止ADC转换ADC_CSR = 0x03; // 选择通道3ADC_TDRL = 0x20;}///////////////读AD值/////////////////////unsigned char read_ad(void){unsigned char i=0;ADC_CR1 = 0x01; // CR1寄存器的最低位置1,使能ADC转换for(i=0;i<100;i++);// 延时一段时间,至少7uS,保证ADC模块的上电完成ADC_CR1 = ADC_CR1 | 0x01;// 再次将CR1寄存器的最低位置1// 使能ADC转换while((ADC_CSR&0x80)==0); // 等待ADC结束i = ADC_DRH; // 读出ADC结果的高8位return(i);}////////////////IO初始化////////////////////void init_gpio(void){//将pb5设置成推挽输出PB_DDR = 0x20; //数据方向PB_CR1 = 0x20; // 上拉、悬空PB_CR2 = 0x00;}/////////////////////////////////////////////main(){unsigned char i=0;init_uart1();init_ad();init_gpio();while (1){delay(1000);i=read_ad();uart1_sendchar(i);PB_ODR^=0x20;}}/////////////////////////////////////////////////*/友情提示:范文可能无法思考和涵盖全面,供参考!最好找专业人士起草或审核后使用,感谢您的下载!。
斯托米2STM32代码

使用原子哥的fsmc寄存器驱动LCD程序,我的RS接在了A0(PF0)其他都和程序里的接法一样,下面红色部分是我修改的部分,现在出现了比较奇怪的现象,就是我把A0弄成推免复位输出就读不到ID,设成其他状态就可以得到ID9320,还请大侠帮帮我分析下,typedef struct{u16 LCD_REG;u16 LCD_RAM;} LCD_TypeDef;//使用NOR/SRAM的 BANK 4,地址位HADDR[27,26]=11 A10作为数据命令区分线//注意设置时STM32内部会右移一位对其! 111110=0X3E#define LCD_BASE ((u32)(0x6C000000 | 0x0C000002))#define LCD ((LCD_TypeDef *) LCD_BASE)--------------------------------------------------------------------------------------------------------void LCD_Init(void){RCC->AHBENR|=1<<8; //使能FSMC时钟RCC->APB2ENR|=1<<3; //使能PORTB时钟RCC->APB2ENR|=1<<5; //使能PORTD时钟RCC->APB2ENR|=1<<6; //使能PORTE时钟RCC->APB2ENR|=1<<7; //使能PORTE时钟RCC->APB2ENR|=1<<8; //使能PORTG时钟RCC->APB2ENR|=1<<0; //使能AFIO时钟GPIOG->CRL&=0XFFFF0FFF;//PG3 推挽输出背光GPIOG->CRL|=0X00003000;//PORTD复用推挽输出GPIOD->CRH&=0X00FFF000;GPIOD->CRH|=0XBB000BBB;GPIOD->CRL&=0XFF00FF00;GPIOD->CRL|=0X00BB00BB;//PORTE复用推挽输出GPIOE->CRH&=0X00000000;GPIOE->CRH|=0XBBBBBBBB;GPIOE->CRL&=0X0FFFFFFF;GPIOE->CRL|=0XB0000000;//PORTF复用推挽输出GPIOF->CRL&=0XFFFFFFF0;GPIOF->CRL|=0X0000000B; //如果去掉就可以得到ID:9320//PORTG12复用推挽输出 A0GPIOG->CRH&=0XFFF0FFFF;GPIOG->CRH|=0X000B0000;GPIOG->ODR |= 1 << 3; //PE0输出高-------------------------------------------------------------------------------------------------------u16 a;int main(void){Stm32_Clock_Init(9);//系统时钟设置delay_init(72);uart_init(72,9600);LCD_Init();LCD_ShowString(0,0,"START INITing...");while(1)//初始化ov7670{a = LCD_ReadReg(0x0000);printf(" LCD ID:%x\n", a ); //打印LCD IDLCD_ShowString(0,0,"TEST OK");delay_ms(511);LCD_ShowString(0,0," ");};}----------------------------------------------------------------------------------------------------------------注销掉GPIOF->CRL&=0XFFFFFFF0;GPIOF->CRL|=0X0000000B;得到的数据USmart处理从PC丢到STM32串口数据的方法:1. 在串口的中断处理函数USART1_IRQHandler将串口数据填在全局数组USART_RX_BUF中;2. 另外有一个Tim2在不停检查标志位SART_RX_STA&0x8000,如果表示串口接收完成,处理全局数组USART_RX_BUF;由于Timer的数量有限,是否可以不使用Timer,直接在串口中断处理函数USART1_IRQHandler中,调用一个函数Parse_Rx_Buf来处理USART_RX_BUF?本人实验下来的结果是:大多数情况下没有问题。
STM8单片机的C语言编程基础与实践

/* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */
main() { while (1); } 而在 stm8_interrupt_vector.c 中,就是声明了对应该芯片的中断向量,如下所示: /* * */ typedef void @far (*interrupt_handler_t)(void); struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; }; @far @interrupt void NonHandledInterrupt (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction BASIC INTERRUPT VECTOR TABLE FOR STM8 devices Copyright (c) 2007 STMicroelectronics
STM8 的 C 语言编程(2)-- 变量空间的分配
采用 C 这样的高级语言,其实可以不用关心变量在存储器空间中是如何具体分配的。但如果了解如何 分配,对编程还是有好处的,尤其是在调试时。 例如下面的程序定义了全局变量数组 buffer 和一个局部变量 i,在 RAM 中如何分配的呢? /* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */ unsigned char buffer[10]; // 定义全局变量
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验1G P I O#include "stm32f10x.h"#include "delay.h"//#include "sys.h"#include "stm32f10x_exti.h"//QHKJ TEB-CM5000实验箱STM32实验1//固件库V3.5工程模板//QHKJGPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;/* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void);void NVIC_Configuration(void);void GPIO_Configuration(void);/* Private functions ---------------------------------------------------------*//****************************************************************************** ** Function Name : main* Description : Main program.* Input : None* Output : None* Return : None******************************************************************************* /int main(void){/* Configure the system clocks */// RCC_Configuration();// SysTick_Configuration();delay_init();/* NVIC Configuration */NVIC_Configuration();/* Configure the GPIO ports */GPIO_Configuration();/* Connect EXTI Line9 to PA.9 */GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource9);/* Configure EXTI Line8 to generate an interrupt on falling edge */EXTI_InitStructure.EXTI_Line = EXTI_Line9;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);for(;;){GPIO_Write(GPIOF, 0xf80f);delay_ms(100);GPIO_Write(GPIOF, 0xf817);delay_ms(100);GPIO_Write(GPIOF, 0xf827);delay_ms(100);GPIO_Write(GPIOF, 0xf847);delay_ms(100);GPIO_Write(GPIOF, 0xf887);delay_ms(100);GPIO_Write(GPIOF, 0x8907);delay_ms(100);GPIO_Write(GPIOF, 0xfa07);delay_ms(100);GPIO_Write(GPIOF, 0xfc07);delay_ms(100);}}** Function Name : NVIC_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;/* Configure one bit for preemption priority */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* Enable the EXTI9_5 Interrupt */// NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}** Function Name : GPIO_Configuration* Description : Configures the different GPIO ports.* Input : None* Output : None* Return : None******************************************************************************* /void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* Enable GPIOA, GPIOF and AFIO clocks */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOF |RCC_APB2Periph_AFIO, ENABLE);/* Configure PF. as Output push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GP IO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOF, &GPIO_InitStructure);/* Configure PA9 as input floating (EXTI Line9) */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOA, &GPIO_InitStructure);}实验7 LED流水灯#include "stm32f10x.h"//QHKJ TEB-CM5000实验箱STM32实验7//固件库V3.5工程模板//QHKJ/*LED灯相关定义*/#define RCC_GPIO_LED RCC_APB2Periph_GPIOF /*LED使用的GPIO 时钟*/#define LEDn 8 /*LED数量*/#define GPIO_LED GPIOF /*LED灯使用的GPIO组*/#define LD1_PIN GPIO_Pin_3 /*LD1使用的GPIO 管脚*/#define LD2_PIN GPIO_Pin_4 /*LD2使用的GPIO管脚*/#define LD3_PIN GPIO_Pin_5 /*LD3使用的GPIO管脚*/#define LD4_PIN GPIO_Pin_6 /*LD4使用的GPIO管脚*/#define LD5_PIN GPIO_Pin_7 /*LD5使用的GPIO 管脚*/#define LD6_PIN GPIO_Pin_8 /*LD6使用的GPIO管脚*/#define LD7_PIN GPIO_Pin_9 /*LD7使用的GPIO管脚*/#define LD8_PIN GPIO_Pin_10 /*LD8使用的GPIO管脚*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure;u8 count=0;/* Private function prototypes -----------------------------------------------*/ //void RCC_Configuration(void);//void NVIC_Configuration(void);void Delay(vu32 nCount);void Turn_On_LED(u8 LED_NUM);/* Private functions ---------------------------------------------------------*//****************************************************************************** ** Function Name : main* Description : Main program.* Input : None* Output : None* Return : None******************************************************************************* /int main(void){/* 配置LED灯使用的GPIO管脚模式*/RCC_APB2PeriphClockCmd(RCC_GPIO_LED, ENABLE); /*使能LED灯使用的GPIO时钟*/GPIO_InitStructure.GPIO_Pin = LD1_PIN|LD2_PIN|LD3_PIN|LD4_PIN|LD5_PIN|LD6_PIN|LD7_PIN|LD8_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIO_LED, &GPIO_InitStructure); /*使用的LED灯相关的GPIO口初始化*/GPIO_ResetBits(GPIO_LED,LD1_PIN|LD2_PIN|LD3_PIN|LD4_PIN|LD5_PIN|LD6_PIN|LD7 _PIN|LD8_PIN);/*关闭所有的LED指示灯*/while(1){GPIO_ResetBits(GPIO_LED,LD1_PIN|LD2_PIN|LD3_PIN|LD4_PIN|LD5_PIN|LD6_PIN|LD7_PIN|LD8_PIN);/*关闭所有的LED指示灯*/Turn_On_LED(count%8); //点亮一个LED灯count++;Delay(0x0FFFFF);}}/*点亮对应灯*/void Turn_On_LED(u8 LED_NUM){switch(LED_NUM){case 0:GPIO_SetBits(GPIO_LED,LD1_PIN); /*点亮LD1灯*/ break;case 1:GPIO_SetBits(GPIO_LED,LD2_PIN); /*点亮LD2灯*/ break;case 2:GPIO_SetBits(GPIO_LED,LD3_PIN); /*点亮LD3灯*/ break;case 3:GPIO_SetBits(GPIO_LED,LD4_PIN); /*点亮LD4灯*/ break;case 4:GPIO_SetBits(GPIO_LED,LD5_PIN); /*点亮LD5灯*/break;case 5:GPIO_SetBits(GPIO_LED,LD6_PIN); /*点亮LD6灯*/break;case 6:GPIO_SetBits(GPIO_LED,LD7_PIN); /*点亮LD7灯*/break;case 7:GPIO_SetBits(GPIO_LED,LD8_PIN); /*点亮LD8灯*/break;default:GPIO_SetBits(GPIO_LED,LD1_PIN|LD2_PIN|LD3_PIN|LD4_PIN|LD5_PIN|LD6_PIN|LD7_PIN|L D8_PIN); /*点亮所有的灯*/break;}}/****************************************************************************** ** Function Name : Delay* Description : Inserts a delay time.* Input : nCount: specifies the delay time length.* Output : None* Return : None******************************************************************************* /void Delay(vu32 nCount){for(; nCount != 0; nCount--);}实验11 串口收发#include "stm32f10x.h"#include "stm32f10x_usart.h"//QHKJ TEB-CM5000实验箱STM32实验11//固件库V3.5工程模板//QHKJ/* Private typedef -----------------------------------------------------------*//*LED灯相关定义*/#define RCC_GPIO_LED RCC_APB2Periph_GPIOF /*LED使用的GPIO 时钟*/#define LEDn 4 /*LED数量*/#define GPIO_LED GPIOF /*LED灯使用的GPIO组*/#define LD1_PIN GPIO_Pin_3 /*LD1使用的GPIO 管脚*/#define LD2_PIN GPIO_Pin_4 /*LD2使用的GPIO管脚*/#define LD3_PIN GPIO_Pin_5 /*LD3使用的GPIO管脚*/#define LD4_PIN GPIO_Pin_6 /*LD4使用的GPIO管脚*//*串口相关定义*/#define USART1_GPIO GPIOA#define USART1_CLK RCC_APB2Periph_USART1#define USART1_GPIO_CLK RCC_APB2Periph_GPIOA#define USART1_RxPin GPIO_Pin_10#define USART1_TxPin GPIO_Pin_9//#define USART1_IRQn USART1_IRQn//#define USART1_IRQHandler USART1_IRQHandler#define USART2_GPIO GPIOA#define USART2_CLK RCC_APB1Periph_USART2#define USART2_GPIO_CLK RCC_APB2Periph_GPIOA#define USART2_RxPin GPIO_Pin_3#define USART2_TxPin GPIO_Pin_2//#define USART2_IRQn USART2_IRQn//#define USART2_IRQHandler USART2_IRQHandlerGPIO_InitTypeDef GPIO_InitStructure;/* Private typedef -----------------------------------------------------------*/ typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;/* Private define ------------------------------------------------------------*/ #define TxBufferSize1 (countof(TxBuffer1) - 1)#define TxBufferSize2 (countof(TxBuffer2) - 1)#define RxBufferSize1 TxBufferSize2#define RxBufferSize2 TxBufferSize1/* Private macro -------------------------------------------------------------*/ #define countof(a) (sizeof(a) / sizeof(*(a)))/* Private variables ---------------------------------------------------------*/ USART_InitTypeDef USART_InitStructure;u8 TxBuffer1[] = "串口中断收发示例: 串口1 -> 串口2 (中断收发)";u8 TxBuffer2[] = "串口中断收发示例: 串口2 -> 串口1 (中断收发)";u8 RxBuffer1[RxBufferSize1];u8 RxBuffer2[RxBufferSize2];u8 TxCounter1 = 0x00;u8 TxCounter2 = 0x00;u8 RxCounter1 = 0x00;u8 RxCounter2 = 0x00;u8 NbrOfDataToTransfer1 = TxBufferSize1;u8 NbrOfDataToTransfer2 = TxBufferSize2;u8 NbrOfDataToRead1 = RxBufferSize1;u8 NbrOfDataToRead2 = RxBufferSize2;u8 TransferStatus1 = FAILED;u8 TransferStatus2 = FAILED;/* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);/* Private functions ---------------------------------------------------------*//*** @brief Main program* @param None* @retval None*/int main(void){/* System Clocks Configuration */RCC_Configuration();/* NVIC configuration */NVIC_Configuration();/* Configure the GPIO ports */GPIO_Configuration();GPIO_ResetBits(GPIO_LED,LD1_PIN|LD2_PIN|LD3_PIN|LD4_PIN);/*关闭所有的LED指示灯*//* USART1 and USART2 configuration ------------------------------------------------------*//* USART1 and USART2 configured as follow:- BaudRate = 9600 baud- Word Length = 8 Bits- One Stop Bit- No parity- Hardware flow control disabled (RTS and CTS signals)- Receive and transmit enabled*/USART_ART_BaudRate = 115200; /*设置波特率为115200*/USART_ART_WordLength = USART_WordLength_8b;/*设置数据位为8*/USART_ART_StopBits = USART_StopBits_1; /*设置停止位为1位*/USART_ART_Parity = USART_Parity_No; /*无奇偶校验*/USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;/*无硬件流控*/USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; /*发送和接收*//*配置串口1 */USART_Init(USART1, &USART_InitStructure);/*配置串口2*/USART_Init(USART2, &USART_InitStructure);/*使能串口1的发送和接收中断*/USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_ITConfig(USART1, USART_IT_TXE, ENABLE);/*使能串口2的发送和接收中断*/USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);USART_ITConfig(USART2, USART_IT_TXE, ENABLE);/* 使能串口1 */USART_Cmd(USART1, ENABLE);/* 使能串口2 */USART_Cmd(USART2, ENABLE);/* Wait until end of transmission from USART1 to USART2 */while(RxCounter2 < RxBufferSize2){}/* Wait until end of transmission from USART2 to USART1 */while(RxCounter1 < RxBufferSize1){}/* Check the received data with the send ones */TransferStatus1 = Buffercmp(TxBuffer2, RxBuffer1, RxBufferSize1);/* TransferStatus1 = PASSED, if the data transmitted from USART2 andreceived by USART1 are the same *//* TransferStatus1 = FAILED, if the data transmitted from USART2 andreceived by USART1 are different */TransferStatus2 = Buffercmp(TxBuffer1, RxBuffer2, RxBufferSize2);/* TransferStatus2 = PASSED, if the data transmitted from USART1 andreceived by USART2 are the same *//* TransferStatus2 = FAILED, if the data transmitted from USART1 andreceived by USART2 are different */while (1){if(TransferStatus1 == PASSED){GPIO_SetBits(GPIO_LED,LD1_PIN);/*点亮LD1,串口1接收的数据与串口2发送的数据相同*/}else if(TransferStatus1 == FAILED){GPIO_SetBits(GPIO_LED,LD2_PIN);/*点亮LD2,串口1接收的数据与串口2发送的数据不相同*/}if(TransferStatus2 == PASSED){GPIO_SetBits(GPIO_LED,LD3_PIN);/*点亮LD3,串口2接收的数据与串口1发送的数据相同*/}else if(TransferStatus2 == FAILED){GPIO_SetBits(GPIO_LED,LD4_PIN);/*点亮LD4,串口2接收的数据与串口1发送的数据不相同*/}}}/*** @brief Configures the different system clocks.* @param None* @retval None*/void RCC_Configuration(void){/*使能串口1和串口2使用的GPIO时钟*/RCC_APB2PeriphClockCmd(USART1_GPIO_CLK |USART2_GPIO_CLK, ENABLE); /* Enable USART1 Clock *//*使能串口1时钟*/RCC_APB2PeriphClockCmd(USART1_CLK, ENABLE);/*使能串口2时钟*/RCC_APB1PeriphClockCmd(USART2_CLK, ENABLE);/*使能LED灯使用的GPIO时钟*/RCC_APB2PeriphClockCmd(RCC_GPIO_LED, ENABLE);}/*** @brief Configures the different GPIO ports.* @param None* @retval None*/void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/*串口1 RX管脚配置*//* Configure USART1 Rx as input floating */GPIO_InitStructure.GPIO_Pin = USART1_RxPin;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(USART1_GPIO, &GPIO_InitStructure);/*串口2 RX管脚配置*//* Configure USART2 Rx as input floating */GPIO_InitStructure.GPIO_Pin = USART2_RxPin;GPIO_Init(USART2_GPIO, &GPIO_InitStructure);/*串口1 TX管脚配置*//* Configure USART1 Tx as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = USART1_TxPin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(USART1_GPIO, &GPIO_InitStructure);/*串口2 TX管脚配置*//* Configure USART2 Tx as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = USART2_TxPin;GPIO_Init(USART2_GPIO, &GPIO_InitStructure);/* 配置LED灯使用的GPIO管脚模式*/GPIO_InitStructure.GPIO_Pin = LD1_PIN|LD2_PIN|LD3_PIN|LD4_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIO_LED, &GPIO_InitStructure);/*** @brief Configures the nested vectored interrupt controller. * @param None* @retval None*/void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;/* Configure the NVIC Preemption Priority Bits */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);/* Enable the USART1 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Enable the USART2 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/*** @brief Compares two buffers.* @param pBuffer1, pBuffer2: buffers to be compared.* @param BufferLength: buffer's length* @retval PASSED: pBuffer1 identical to pBuffer2* FAILED: pBuffer1 differs from pBuffer2*/TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength) {while(BufferLength--){if(*pBuffer1 != *pBuffer2){return FAILED;}pBuffer1++;pBuffer2++;}return PASSED;}/*** @brief This function handles USART1 global interrupt request. * @param None* @retval None*/void USART1_IRQHandler(void){if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){/* Read one byte from the receive data register */RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);if(RxCounter1 == NbrOfDataToRead1){/* Disable the USART1 Receive interrupt */USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);}}if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET){/* Write one byte to the transmit data register */USART_SendData(USART1, TxBuffer1[TxCounter1++]);if(TxCounter1 == NbrOfDataToTransfer1){/* Disable the USART1 Transmit interrupt */USART_ITConfig(USART1, USART_IT_TXE, DISABLE);}}}/*** @brief This function handles USART2 global interrupt request. * @param None* @retval None*/void USART2_IRQHandler(void){if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){/* Read one byte from the receive data register */RxBuffer2[RxCounter2++] = USART_ReceiveData(USART2);if(RxCounter2 == NbrOfDataToRead1){/* Disable the USART2 Receive interrupt */USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);}}if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) {/* Write one byte to the transmit data register */ USART_SendData(USART2, TxBuffer2[TxCounter2++]);if(TxCounter2 == NbrOfDataToTransfer2){/* Disable the USART2 Transmit interrupt */USART_ITConfig(USART2, USART_IT_TXE, DISABLE); }}}。