STM8单片机 UART发送完成中断C语言程序
stm8笔记2-定时3更新中断+pwm输出(IDE为IAR)
stm8笔记2-定时3更新中断+pwm输出(IDE为IAR)⼀:IAR编译器中断函数说明下⾯说⼀下在IAR下,在IAR下必须要添加iostm8s105s6.h⽂件,在⽂件的最后有如下内容:/*-------------------------------------------------------------------------* Interrupt vector numbers*-----------------------------------------------------------------------*/#define AWU_vector 0x03#define SPI_TXE_vector 0x0C#define SPI_RXNE_vector 0x0C#define SPI_WKUP_vector 0x0C#define SPI_CRCERR_vector 0x0C#define SPI_OVR_vector 0x0C#define SPI_MODF_vector 0x0C#define TIM1_OVR_UIF_vector 0x0D#define TIM1_CAPCOM_BIF_vector 0x0D#define TIM1_CAPCOM_TIF_vector 0x0D#define TIM1_CAPCOM_CC1IF_vector 0x0E#define TIM1_CAPCOM_CC2IF_vector 0x0E#define TIM1_CAPCOM_CC3IF_vector 0x0E#define TIM1_CAPCOM_CC4IF_vector 0x0E#define TIM1_CAPCOM_COMIF_vector 0x0E#define TIM2_OVR_UIF_vector 0x0F#define TIM2_CAPCOM_CC1IF_vector 0x10#define TIM2_CAPCOM_TIF_vector 0x10#define TIM2_CAPCOM_CC2IF_vector 0x10#define TIM2_CAPCOM_CC3IF_vector 0x10#define UART1_T_TXE_vector 0x13#define UART1_T_TC_vector 0x13#define UART1_R_OR_vector 0x14#define UART1_R_RXNE_vector 0x14#define UART1_R_IDLE_vector 0x14#define UART1_R_PE_vector 0x14#define UART1_R_LBDF_vector 0x14#define I2C_ADD10_vector 0x15#define I2C_ADDR_vector 0x15#define I2C_OVR_vector 0x15#define I2C_STOPF_vector 0x15#define I2C_BTF_vector 0x15#define I2C_WUFH_vector 0x15#define I2C_RXNE_vector 0x15#define I2C_TXE_vector 0x15#define I2C_BERR_vector 0x15#define I2C_ARLO_vector 0x15#define I2C_AF_vector 0x15#define I2C_SB_vector 0x15#define ADC1_AWS0_vector 0x18#define ADC1_AWS1_vector 0x18#define ADC1_AWS2_vector 0x18#define ADC1_AWS3_vector 0x18#define ADC1_AWS4_vector 0x18#define ADC1_AWS5_vector 0x18#define ADC1_AWS6_vector 0x18#define ADC1_EOC_vector 0x18#define ADC1_AWS8_vector 0x18#define ADC1_AWS9_vector 0x18#define ADC1_AWDG_vector 0x18#define ADC1_AWS7_vector 0x18#define TIM4_OVR_UIF_vector 0x19#define FLASH_EOP_vector 0x1A#define FLASH_WR_PG_DIS_vector 0x1A对照中断向量表,如果⽤到中断,必须⾃⼰写中断,⽐如TIM3定时器中断#pragma vector=TIM3_OVR_UIF_vector__interrupt void TIM3_UPD_OVF_IRQHandler (void){TIM3_SR = 0X00;//清除中断标志}⽤关键字#pragma vector=指出本中断处理函数指向的中断号,⽤关键字__interrupt作为函数的前缀,表⽰这是中断处理函数。
STM8单片机ADC、Timer、USART寄存器直接操作实用例程
STM8 单片机ADC、Timer、USART实用例程这是一个我花了较长时间摸索出来的STM8L-051的例程,它控制LED灯,Timer2定时100us进入中断,软件启动ADC,采样10 次后取平均,将结果通过UASART发送至PC 机,在超级终端上显示的实用程序,因其内存极小,不能用printf等函数,因此对于想用这款资源极少的MCU的开发者来说,读这篇文章会大大节约你的研发时间。
有不会的问题请发邮件***************。
#include <stdio.h>#include "stm8l15x.h"#include "iostm8l051f3.h"#define LED_GPIO_PORT GPIOA#define LED_GPIO_PINS GPIO_Pin_2 | GPIO_Pin_3/* Private function prototypes -----------------------------------------------*/#define ADC1_DR_ADDRESS ((uint16_t)0x5344)#define BUFFER_SIZE ((uint8_t) 0x02)#define BUFFER_ADDRESS ((uint16_t)(&Buffer))#define ASCII_NUM_0 ((uint8_t) 48)#define ADC_RATIO ((uint16_t) 806) /*ADC_RATIO = ( 3.3 * 1000 * 1000)/4095*/#define SampleADC ((uint8_t) 0x0A)/* Private variables ---------------------------------------------------------*/uint8_t Buffer[4] = {0, 0, 0, 0};uint16_t ADCdata = 0;uint16_t ADCvalue = 0;unsigned char LED =1;unsigned char c = 8;uint16_t acode = 1234; //43 "+" 0x2B;void Delay(__IO uint16_t nCount){/* Decrement nCount value */while (nCount != 0){nCount--;}}//int putchar(int c)//{// while ((USART1_SR&0x80)==0x00);// UART2_sendchar((u8)c);// return (c);//}static void CLK_Config(void){/* Select HSI as system clock source */CLK_SYSCLKSourceSwitchCmd(ENABLE);CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI); /*High speed external clock prescaler: 1*/CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSI){}/* Enable ADC1 clock */CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);/* Enable DMA1 clock */// CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);/* Enable TIM2 clock */CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE); }static void GPIO_Config(void){PC_DDR = 0X20;PC_CR1 = 0X20;PA_DDR = 0X0C;PA_CR1 = 0X0C;}static void USART1_Config(void){// ADCvalue = USART1_DR;USART1_BRR2 = 0x03;USART1_BRR1 = 0x68; //16M/9600=683USART1_CR2 = 0x0C; //Transmitter & receiver enable}static void ADC_Config(void){ADC1_CR2 = 0x22; //risign edge, softwae start, sampling time 16 ADC clockADC1_SQR3 = 0x80; //ADC = 15channelADC1_TRIGR1 = 0x10; //use internal ref,sampling time 16 ADC clock for RefRI_ASCR1 = 0x00;}void TIM2_Config(void){TIM2_PSCR = 0x07; // 应是16,但只能置三位,所以是111 fCK_PSC / 2(PSC[2:0]).// TIM2_PSCRL = 0x3F; // PSCR=0x1F3F,f=8M/(0x1F3F+1)=1000Hz,每个计数周期1ms TIM2_ARRH = 0x00; // 自动重载寄存器ARR=0x01F4=500TIM2_ARRL = 0x18; // 24X4us=96us 每记数500次产生一次中断,即500msTIM2_IER = 0x01; // 允许更新中断TIM2_CR1 = 0x05; // 计数器使能,开始计数,只允许更新中断请求}void Delay (uint16_t nCount);/* Private functions ---------------------------------------------------------*///#pragma vector = ADC1_EOC_vector//__interrupt void ADC1_EOC(void)//{// ADCdata = ADC_GetConversionValue(ADC1);// }#pragma vector =TIM2_OVR_UIF_vector__interrupt void TIM2_OVR_UIF(void){asm("sim");static uint8_t measurements = SampleADC;static uint32_t accumulator = 0;uint32_t average = 0;uint16_t factor10 = 1000;int8_t i ;ADCdata = 0;TIM2_SR1 = 0x00; //Clear UIFADC1_SR = 0x00; //Clear EOCADC1_CR1 = 0x03; // EOC interrupt unable, software set start, ADC enable// while (!(ADC1_SR & 0x01));/*最后一位不是1,结果就是全零,结果为False,!则是True,循环下去;若是1,则跳出。
STM8S103F3P中断形式执行硬件I2C
{
ErrorStatus Swif = ERROR;
while(!I2CCheckERREN()) {
I2CInit(); } if(!I2CFunction) {
if(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)) {
I2C_Cmd(DISABLE); I2CSoftStop(); I2C_Cmd(ENABLE); } if(!I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)) { I2CFunction=1; I2CDirection=I2C_DIRECTION_TX;//I2C_DIRECTION_RX I2CSlaveAddress=SlaveAddress; I2CRegisterAddress=RegisterAddress; pI2CWriteData=pWriteData; I2C_AcknowledgeConfig(I2C_ACK_CURR); I2C_GenerateSTART(ENABLE); Swif = SUCCESS; } } return(Swif); }
* @retval ErrorStatus:ERROR 调用失败,SUCCESS 调用成功
*/
ErrorStatus I2CWriteData(uint8_t SlaveAddress, uint8_t RegisterAddress,
*pWriteDataBuffer, uint8_t WriteDataCount)
I2CInit(); } if(!I2CFunction) {
if(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)) {
I2C_Cmd(DISABLE); I2CSoftStop(); I2C_Cmd(ENABLE); } if(!I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)) { I2CFunction=4; I2CDirection=I2C_DIRECTION_TX;//I2C_DIRECTION_RX I2CSlaveAddress=SlaveAddress; I2CRegisterAddress=RegisterAddress; pI2CDataBuffer=pReadDataBuffer; I2CDataCount=ReadDataCount; I2C_AcknowledgeConfig(I2C_ACK_CURR); I2C_GenerateSTART(ENABLE); Swif = SUCCESS; } } return(Swif); }
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;}}/////////////////////////////////////////////////*/友情提示:范文可能无法思考和涵盖全面,供参考!最好找专业人士起草或审核后使用,感谢您的下载!。
STM8003F3串口通信程序
头文件:Uart.h#ifndef _UART_H_#define _UART_H_#include"DataType.h"void Uart1_Init(u16 SYS_Clk, u32 baud);void Uart1_SendData(u8 data);void Uart1_IOConfig(void);extern u8 RecData;extern u8 flag;#endif源文件:Uart.c#include"iostm8s.h"#include"Uart.h"u8 RecData;u8 i=0;u8 flag;void Uart1_Init(u16 SYS_Clk, u32 baud){u16 UART_Temp=0;Uart1_IOConfig();USART1_CR2 = 0;// 禁止UART发送和接收USART1_CR1 = 0x00; //8bitUSART1_CR3 = 0x00; //1 stop bit// USART1_BRR2 = 0x0D;// USART1_BRR1 = 0x00; //9600 baud rate/************************************************** 设置波特率,必须注意以下几点:(1) 必须先写BRR2(2) BRR1存放的是分频系数的第11位到第4位,(3) BRR2存放的是分频系数的第15位到第12位,和第3位到第0位例如对于波特率位9600时,分频系数=2000000/9600=208对应的十六进制数为00D0,BBR1=0D,BBR2=00*************************************************/ UART_Temp = SYS_Clk*1000000/baud;USART1_BRR2 = (u8)((UART_Temp&0x000F)|((UART_Temp&0xF000)>>8));USART1_BRR1 = (u8)((UART_Temp&0x0FF0)>>4);USART1_CR2 = 0x2C; // b3 = 1,允许发送// b2 = 1,允许接收// b5 = 1,允许产生接收中断}@far @interrupt void USART1_RX_IRQHandler (void){u8 RxBuffer;RxBuffer = USART1_DR; //Store the received byte in RxBuffer//Uart1_SendData(Rec_whole[w]);RecData=RxBuffer&0x0ff;return;}void Uart1_SendData(u8 data){while((USART1_SR & 0x80) == 0x00); // 若发送寄存器不空,则等待USART1_DR = data; // 将要发送的字符送到数据寄存器}void Uart1_IOConfig(void){PD_DDR |= (1<<5);//输出模式 TXDPD_CR1 |= (1<<5);//推挽输出PD_DDR &=~(1<<6);//输入模式 RXDPD_CR1 &=~(1<<6);//浮空输入}。
【STM32】关于UART2发送后中断常犯错误大全,你中招了吗?
【STM32】关于UART2发送后中断常犯错误大全,你中招了吗?先说TC。
即Transmission Complete。
发送一个字节后才进入中断,这里称为“发送后中断”。
和原来8051的TI方式一样,都是发送后才进中断,需要在发送函数中先发送一个字节触发中断。
发送函数如下/*******功能:中断方式发送字符串。
采用判断TC的方式。
即判断发送后中断位。
输入:字符串的首地址输出:无*******/void USART_SendDataString( u8 *pData ){pDataByte = pData;USART_ClearFlag(USART1,USART_FLAG_TC);//清除传输完成标志位,否则可能会丢失第1个字节的数据。
网友提供。
USART_SendData(USART1,*(pDataByte++)); //必须要++,不然会把第一个字符t发送两次}中断处理函数如下/********* Function Name : USART1_IRQHandler* Description :This function handles USART1 global interrupt request.* Input : None* Output : None* Return : None*********/void USART1_IRQHandler(void){if( USART_GetITStatus(USART1, USART_IT_TC) == SET ){if( *pDa taByte == ‘\0’ )//TC需要读SR+写DR 方可清0,当发送到最后,到‘\0’的时候用个if判断关掉USART_ClearFlag(USART1, USART_FLAG_TC);//不然TC一直是set,TCIE也是打开的,导致会不停进入中断。
clear掉即可,不用关掉TCIEelseUSART_SendData(USART1, *pDataByte++ );}}其中u8 *pDataByte;是一个外部指针变量在中断处理程序中,发送完该字符串后,不用关闭TC的中断使能TCIE,只需要清掉标志位TC;这样就能避免TC == SET 导致反复进入中断了。
青风STM8开发板寄存器教程第五节串口UART(寄存器)
青风带你学stm8系列教程-------------寄存器操作版本出品论坛:青风电子社区作者:青风出品论坛:淘宝店:QQ技术群:371153390硬件平台:QF-STM8开发板2.5串口通信的实现2.5.1原理分析串口通信也称为异步串行通信,学过51的同学都会知道串口通信。
串口是计算机上一种非常通用设备通信的协议。
大多数计算机包含两个基于RS232的串口。
串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。
同时,串口通信协议也可以用于获取远程采集设备的数据。
串口通信的概念非常简单,串口按位(bit)发送和接收字节。
通信使用3根线完成:(1)地线,(2)发送,(3)接收。
由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。
其他线用于握手,但是不是必须的。
串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。
对于两个进行通信的端口,这些参数必须匹配:a,波特率:这是一个衡量通信速度的参数。
它表示每秒钟传送的bit的个数。
例如300波特表示每秒钟发送300个bit。
当我们提到时钟周期时,我们就是指波特率例如如果协议需要4800波特率,那么时钟是4800Hz。
这意味着串口通信在数据线上的采样率为4800Hz。
通常电话线的波特率为14400,28800和36600。
波特率可以远远大于这些值,但是波特率和距离成反比。
高波特率常常用于放置的很近的仪器间的通信,波特率除数(baud-rate divisor)是一个22位数,它由16位整数和6位小数组成。
波特率发生器使用这两个值组成的数字来决定位周期。
通过带有小数波特率的除法器,在足够高的系统时钟速率下,UART可以产生所有标准的波特率,而误差很小。
波特率除数公式:BRD=BRDI.BRDF=SystemClock/(16×BaudRate)其中:BRD是22位的波特率除数,由16位整数和6位小数组成BRDI是BRD的整数部分BRDF是BRD的小数部分SystemClock是系统时钟(UART模块的时钟直接来自SystemClock)BaudRate是波特率(9600,38400,115200等)b,数据位:这是衡量通信中实际数据位的参数。
IAR for stm8平台 寄存器版 串口通信 实验程序
18 #endif /* __UART_H */
19
20
21 //"uart.c" 程序文件
22 #include "uart.h"
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #define HSIClockFreq 16000000
27 #define BaudRate 38400
42
43
UART1_CR5 = (0<<2)|(0<<1);
44
//使用智能卡模式需要设置的,可以不Fra bibliotek改45
46
//设置波特率
47
baud_div =HSIClockFreq/BaudRate; //分频因子
48
UART1_BRR2 = baud_div & 0x0f;
49
UART1_BRR2 |= ((baud_div & 0xf000) >> 8);
75
UART1_Re_Buf=((uint8_t)UART1_DR);
76
return UART1_Re_Buf;
77 }
78
79
80
81
82 int fputc(int ch, FILE *f)
83 {
84 /*将Printf内容发往串口*/
85 UART1_DR=(unsigned char )ch;
86 while (!(UART1_SR & UART1_FLAG_TXE));
87 return (ch);
88 }
STM8教程-第十二章-串口及其应用
STM8教程-第十二章-串口及其应用第十二章串口及其应用前面三节介绍了 STM8 的 IO 口以及时钟编程。
这一节我们将学习 STM8 的串口。
通过本节学习,你将了解到 STM8 串口的基本使用方法。
前面三节介绍了STM8的IO口操作以及时钟编程。
这一节我们将学习STM8的串口。
作为软件开发重要的调试手段,串口的作用是很大的。
在调试的时候可以用来查看和输入相关的信息。
在使用的时候,串口也是一个和外设(比如GPS,GPRS模块等)通信的重要渠道。
STM8的串口资源相当丰富的,功能也相当强劲。
STM8有波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDA SIR ENDEC规范接下来我们将从寄存器层面,告诉您如何设置串口,以达到我们最基本的通信功能。
本实例中,我们将实现利用串口1不停的打印一个信息到电脑上,以及例程二的同时接收从串口发过来的数据,把发送过来的数据直接送回给电脑。
串口最基本的设置,就是波特率的设置。
STM8 的串口使用是很简单的。
UARTD 是 UART 的使能位,0的时候使能UART,1的时候不可以用 UART,默认 0,M 是定义串口的字长,0为8位字长,1是9位的字长下面的 PECE,PS,PIEN 分别是奇偶效验,奇偶效验选择,效验中断使能。
由于我们没有定义奇偶效验在此不再详细说明,默认就可以。
1、UARTx_CR2控制寄存器 2 主要负责管理中断和发送接收的使能TIEN、TCIEN、RIEN、ILIEN 分别对应发送中断,发送完成中断,接收中断以及IDLE 中断TEN 是发送使能,当 TEN = 1 的时候我们就可以通过串口进行发送数据,当然前提是我们已经设置好对应的寄存器REN 是接收使能,当 REN = 1 的时候我们可以通过串口接收其它设备的数据RWU 接收唤醒SBK 发送断开帧2、UARTx_CR3在这个寄存器中我们主要使用了 STOP,也就是设置停止位数LINEN Lin 模式的使能,这里我们不详细说明STOP 设置停止位数 00 1 个停止位01 保留10 2 个停止位11 1.5 个停止位CLKEN 时钟使能,由于我们没有采用 3 根线,只用了 UART_RX 和 UART_TX 所以不需要设置这个寄存器,默认就可以CPOL、CPHA、LBCL 对应着的是时钟极性,时钟相位以及最后一个时钟脉冲,详细介绍请见寄存器手册3、波特率有关寄存器4、数据寄存器发送和接受的数据通过这个寄存器的读写就可以实现5、状态寄存器通过读取这个寄存器可以知道 UART 的工作状态我们本实验就需要查询这个寄存器的某个位,来清除数据是否发送完毕TXE 发送数据寄存器空0 的时候非空,1 为空TC 发送完成0 未完成 1 完成发送RXNE 读数据寄存器非空0 数据没有收到 1 数据收到其它的位分别为检查到 IDLE 总线,过载错误,噪声标志位,帧错误,奇偶效验错误简单的寄存器就结束到此,除此之外还有其它很多寄存器望读者查阅寄存器手册有了以上的基础,我们可以开始这一节的软件编写了在开始软件代码编程之前,先说明一下我们的硬件我们的实验板是共用一根 USB 线实现多功能操作,分别是下载程序功能,供电功能以及串口功能,传统的串口需要串口接口,考虑到方便我们自己通过 PL2303把串口转成可以通过 USB 进行通信,下面开始我们的例程一,简单的发送数据给终端例程一、简单数据发送#include "iostm8s207rb.h"void delay_ms(int value);int main( void ){unsigned char temp = 0;CLK_CKDIVR = 0x00; //主频为16MUART1_CR1 = 0x00; //关闭UART,设置数据位8位,禁止奇偶效验,禁止中断UART1_CR3 = 0x00; //一位停止位,默认值UART1_BRR2 = 0x0b; //设置波特率为115200UART1_BRR1 = 0x08;UART1_CR2_TEN = 1; //使能发送while(1){while(!UART1_SR_TC); //等待一帧发送完毕,再传送下一帧UART1_DR = temp;temp++;if(temp>=255)temp = 0;delay_ms(100);}}/************************************ *********简单延时程序*********************************** **********/void delay_ms(int value){int i,j;if(value < 1)value = 1;for(i=0;i!=value;++i)for(j=0;j!=5000;++j);}编译下载后,打开串口调试助手,复位单片机就可以看到对应的数据输出,如下图:可以看出是从 0 递进的数,因为我们的串口设置是 115200 波特率,所以串口调试助手也对应这个波特率例程二、串口接收及发送我们实现的功能是通过串口接收电脑的数据,并把对应的数据发送给电脑。
IARFORSTM8例程要点总结计划
IAR+STM8 ——EXTI外面中断控制寄存器2013-03-2123:23:15| 分类:STM8|举报|字号订阅这块三合一的开发板上有且只有一个按键,没方法,就拿这唯一的按键来用吧。
吸取前面UART3的教训,先看开发板的原理图吧。
这个按键被接到了STM8S207SB的PD7上,已做了上拉办理。
为了简单了然,还是点LED1吧。
按一下LED1亮,再按一下LED1灭。
好了,写程序吧。
include<iostm8s207sb.h>#defineLED1_FLASHPD_ODR_ODR3=!PD_ODR_ODR3//开发板上的LED1接在PD3上voidGPIO_init(void){PD_DDR=0x08;//配置PD端口的方向寄存器PD3输出PD_CR1=0x08;//设置PD3为推挽输出PD_CR2=0x80;//使能PD7外面中断}voidEXTI_init(void){EXTI_CR1=0x80;//PD口下降沿触发中断}#pragmavector=0x02//这里很要点!看下面说明。
__interruptvoidEXTI_PD7_TLI(void){LED1_FLASH;}voidinit_devices(void){asm("sim");//关全局中断GPIO_init();EXTI_init();asm("rim");//开全局中断}voidmain(void){init_devices();主循环里没有程序需要执行while(1);}这里重视要说明的一点是PD7的外面中断程序。
看了一下芯片手册,PD口外面中断EXTI3的中断向量号是6,想自然,又是想自然,按IAR的规矩中断向量要加2,就这样写#pragmavector=0x08,结果就是按下按键,程序没响应了,素来在中断里不出来。
接下来只能另想方法,仔细翻了资料后发现,PD7和PD其他端口不同样,PD7后边拖了个小尾巴TLI,再看手册上的TLI描述,乖乖,TLI拥有芯片最高等别中断,享有独立专用的中断向量号0,这下就好办了,按IAR的规矩,向量号加2,程序改成#pragmavector=0x02,重新来一遍编译、下载、运行,按键终于听话了。
UART串口通讯(中断)
• UART接收FIFO缓冲区
UnRSR
• UART0、UART1各含有1 个16字节的接收FIFO缓冲 区。 • 软件设置接收FIFO缓冲区 的触发字节。
RXD
接收FIFO
UnFCR
UnRBR
UART FIFO控制寄存器 位 功能 7 6 [5 : 3] — 2 复位TxFIFO 1 复位RxFIFO 0 使能FIFO Rx触发点设置
中断服务函数
• void UART0_IRQHandler(void) • {int i; • switch(U0IIR & 0x0f) • { • case 0x04: //RxFIFO达到14字节 • for(i=0;i<13;i++) RcvBuf[RcvP++]=U0RBR; break; • case 0x0c: //接收超时, 表示数据结束 • while(U0LSR & 0x01) RcvBuf[RcvP++]=U0RBR; • RcvL=RcvP; //一帧数据结束标志 • RcvP=0; break; //准备接受下一数据 • case 0x02: //发送缓冲器空 • if(TxdP==TxdL) {U0IER = 0X05; // THRE中断禁止 • TxdL=TxdP=0;} • else {for(i=16;i>0;i--) {if(TxdP==TxdL) break; //发送字符完 • else U0THR = TxdBuf[TxdP++];} } break; • case 0x06: //状态中断 • RcvL=U0LSR; //读状态, 清除错误标志 • RcvP=RcvL=TxdP=RxdL=0; break; • } }
STM8单片机中断的主要功能解析
STM8 单片机中断的主要功能解析
内部中断:一般是由硬件错误或者运算过程中出错引起的,一般是不可避免的;
外部中断:是处理器的外设发出的中断请求,如定时器中断,UART 接收中断,外部中断一般都可以通过中断控制器进行屏蔽;
1.ITC 功能概述:
……所有IO 引脚都具有外部中断能力,每个端口都有独立的中断向量以及独立的标志;外设中断能力;
……软件中断能力(TRAP)
……具有灵活的优先级和中断等级管理,支持可嵌套和同级中断管理:——多达4 个软件可编程的嵌套等级;——最多有32 个中断向量,其入口地址由硬件固定;——2 个不可避免的中断:RESET,TRAP;——1 个不可避免的最高优先级硬件中断TL1;。
STM8教程-第九章STM8S207中断系统解析
STM8S207共有9个复位源:
1、NRST引脚产生的外部复位
2、上电复位(POR)
3、掉电复位(BOR)
4、独立看门狗复位
5、窗口看门狗复位
6、软件复位
7、SWIM复位
8、非法操作码复位
9、EMS复位:当一些关键的寄存器被破坏或错误加载时产生的复位
所有的复位源最终都作用于NRST管脚,并在复位过程中保持低电平。复位入口向量在内存映射中位于固定的地址6000h。
9.1.2STM8S207单片机的中断
STM8S单片机的中断分为可屏蔽中断和不可屏蔽中断。
1、不可屏蔽中断
不可屏蔽中断包括软件中断、复位中断以及TLI中断,下面简要介绍常用的几个不可屏蔽中断。
(1)软件中断
TRAP实质上是条指令,但其执行过程与中断相同,即通过中断矢量确定目标地址,中断矢量是8004H~8007H。
本实例中关于LED灯的实现已经在前面章节中介绍过,本章介绍中断服务程序的编写。由中断矢量表可以查到TLI的中断号为0,而在IAR下加2就是2。
TLI中断编写顺序为:
初始化对应IO口中断模式,这里就是PD7口,通过CR1,CR2设置
初始化对应中断的方式,例如TLI就是EXTI_CR2的第三位,默认是0,也就是下降沿触发。
STM8S207默认的中断处理机制如下图所示:
9.2.2嵌套中断管理模式
在该模式下,允许在中断子程序中响应中断。一旦一个中断的优先级被设置低于3级时该模式就立即有效。
注意:在中断被响应时如果位I1和I0被修改,那么设备将作如下处理:如果一个中断X仍然处在悬起状态(新的中断或者中断标志没有被清除)同时该新的优先级又比先前的优先级高的话,那么该中断X会被重新响应。否则该中断的软件优先级在下一个中断请求( X中断的IRET之后)来之前保持不变。
STM8串口收发(典型)
最近开始使用stm8s103k3单片机了。
据说很好,确实不错。
前几天已经试过了GPIO,Timer2,ADC的功能,唯独串口UART使用,破费周折,写出来,供大家借鉴。
我使用的是stm8s103k3,32脚单片机,这个使用手册上说了UART1,UART2,UART3。
但是引脚的功能图上只有你打开stm8s103k.h的头文件,里面也只有UART1寄存器的定义说明。
所以我认为只有UART1。
既然有这个功吧,我以为直接可以连接到电脑的串口(COM1),就可以使用了,其实不可以。
单片机即使写着提供UART通讯接MAX232转接芯片,我就在这里耽误了许多时间。
1、使用stm8s103上的串口和计算机com口通许的硬件连接:2、软件设置(1)发送数据配置1)编程UART_CR1的M位来定义字长。
2)在UART_CR3中编程停止位的位数。
3)按下列顺序编写波特率寄存器选择要求的波特率。
a)UART_BRR2b)UART_BRR14)设置UART_CR2中的TEN位来使能发送5)把要发送的数据写进UART_DR寄存器main.c程序如下:#include "stm8s103k.h"void UART1_Init(void){UART1_CR2=0x00;//使发送禁用TEN=0;UART1_CR1=0x00;//设置M字长,8位数据位UART1_CR3=0x00;//1位停止位UART1_BRR2=0x00;//00-0d:9600(fcpu=fmaster=2MHz)UART1_BRR1=0x0d;//00-1a:4800; 01-34:2400UART1_CR2=0x08;}main(){//fmaster=fcpu=2MHzCLK_ECKR=0x00;CLK_ICKR=0x01;CLK_CMSR=0xe1;CLK_SWR=0xe1;CLK_CKDIVR=0x18;UART1_Init();while (1){unsigned char i;while(!(UART1_SR & 0x80));//发送寄存器数据是否转移完UART1_CR2=0x00;//a处UART1_DR=0xB6;//要发送的数据UART1_CR2=0x08;//b处while((UART1_SR & 0x40) ==0);//发送是否完成}}上面的代码是我反复实验过的,如果不加a和b处代码,则接收的数据不稳定,比如发送5,接收到的数据的串则接收的数据可能是0xB6,或0x67,或0x3B.(2)接收数据1)编程UART_CR1的M位来定义字长。
STM8 COSMIC 中断
W\SHGHI YRLG #IDU LQWHUUXSWBKDQGOHUBW YRLG t)-
LQWHUUXSWBKDQGOHUBW"LQWHUUXSWBKDQGOHU>ń P t)- " LQWHUUXSWBYHFWRU
LQWHUUXSWBYHFWRU<FRQVW>BYHFWDE>@ ń P t)- ˍ (/ ඪ
¹YHFWRU ILOH QDPHƑ
(</Ʋ
3Ǹ၏BBYHFWDEּ) ˫ p ּ̤-YHFWRU DGGUH
ޖVWPBLQWHUUXSWBYHFWRUOV-
Ƒ ˷v
ܼ̤ ּ)
p%
BBYHFWDE GFE GFE SDJH BBVWH[W GFZ BBVWH[W GFE GFE SDJH IB1RQ+DQGOHG,QWHUUXSW GFZ IB1RQ+DQGOHG,QWHUUXSW
జ
D F G H
D F G H
LUTBV\VWHPBWLPBRYI
ͩ$ " t
Ƒ
PV
జ
ˣ Ϥ
Ϥ ַę "L ַȒ#
Ȓ# ˷v ę [ś #IDU #LQWHUUXSW YRLG LUTBV\VWHPBWLPBRYI ^
LI V\VWHPBGHOD\ ^ V\VWHPBGHOD\
Ƒܼ ̤ / ̤
1RQ+DQGOHG,QWHUUXSW ּ" జ /LQWHUUXSWBKDQGOHUBW LQWHUUXSWBKDQGOHU #- / ń ࡙3
完整word版,STM32Uart串口中断响应、发送接收详细程序
程序实现功能:可以直接接收USART1的数据,并通过串口调试输出显示#i nclude"stm32f10x_lib.h"void NVIC_C on figuratio n( void);void RCC_Co nfiguratio n( void);void GPIO_C on figuratio n( void);ErrorStatus HSEStartUpStatus;USART_I ni tTypeDef USART_I ni tStructure;USART_Clockl ni tTypeDef USART_Clockl ni tStructure;int mai n(){#ifdef DEBUGdebug#en difRCC_Co nfiguratio n();NVIC_Co nfiguratio n();GPIO_C on figuratio n();/*串口传输速率的大小必须与RCC所设定的时钟相对应起来*/USART_ART_BaudRate = 9600; //设置USART 的传输速率/*设定数据的接收发送模式*/USART_ART_WordLength = USART_WordLength_8b;〃在一帧中传输或接受8位数据位USART_I ART_StopBits = USART_StopBits_1; // 定义在帧的结尾传输一个停止位USART_I ni ART_Parity = USART_Parity_No; // 奇偶失能USART_I ni ART_HardwareFlowCo ntrol = USART_HardwareFlowC on trol_No ne; //指定硬件流控制模式RTS和CTS使能USART_I ni ART_Mode = USART_Mode_Rx | USART_Mode_Tx; 〃指定使能或失能发送和接受模式Tx发送使能和Rx接收使能USART_ Clock ART_Clock = USART_Clock_Disable;钟时使能还是失能,钟低电平活动USART_ClockI ni ART_CPOL = USART_CPOL_Low; 上时钟的极性USART_ClockI ni ART_CPHA = USART_CPHA_2Edge;进行数据捕获USART_ClockI ni ART_LastBit = USART_LastBit_Disable;输出最后发送的那个数据字的脉冲不从SCLK输出USART_ClockI nit(USART1, & USART_Clockl ni tStructure);USART_I nit(USART1, & USART」ni tStructure);/*输入输出的中断使能*/// USART_ITCo nfig(USART1, USART_IT_TXE, ENABLE);〃提升USART时//指定SLCK引脚//时钟第二个边缘//在SCLK引脚上USART_ITCo nfig(USART1, USART_IT_RXNE, ENABLE);USART_Cmd(USART1, ENABLE); //启动串口 使能 USART1 夕卜设while(1) { } /*USART_Se ndData(USART1, 0X26); // 发送数据while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}〃 等待发送结束*/}void NVIC_Co nfiguratio n( void) {NVIC_I ni tTypeDef NVIC_I ni tStructure; #ifdef VETB_TAB_RAMNVYC_SetVectorTable(NVIC_VectTab_RAM,0x0); #elseNVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #en dif/* En able the USART1 In terrupt */NVIC_I ni tStructure.NVIC_IRQCha nnel = USART1_IRQCha nnel; 断(故后面应选择在“ void USART1_IRQHandler(void) ”开中断) NVIC_I ni tStructure.NVIC_IRQCha nn elPreemptio nPriority = 0; NVIC_I ni tStructure.NVIC_IRQCha nn elSubPriority = 0; NVIC_I ni tStructure.NVIC_IRQCha nn elCmd = ENABLE; NVIC_I nit(&N VIC_I nitStructure); }void RCC_Co nfiguratio n( void) {RCC_DeI nit();RCC_HSEC on fig(RCC_HSE_ON);HSEStartUpStatus=RCC_WaitForHSEStartUp(); if(HSEStartUpStatus==SUCCESS) {FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_E nable); FLASH_SetLate ncy(FLASH_Late ncy_2); RCC_HCLKCo nfig(RCC_SYSCLK_Div1); RCC_PCLK2Co nfig(RCC_HCLK_Div1); // 串口波特率的确定RCC_PCLK1Co nfig(RCC_HCLK_Div2);RCC_PLLCo nfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY==RESET)) {} RCC_SYSCLKCo nfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource()!=0x08){}〃通道设置为串口 1中 〃中断占先等级0 〃中断响应优先级0//打开中断}RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPI0A |RCC_APB2Periph_GPI0E|RCC_APB2Periph_USART1, ENABLE); 〃RCC 中打开相应的串口}void GPIO_C on figuratio n(void){GPIO_I ni tTypeDef GPIO_I nitStructure;// GPIO_Pi nRemapCo nfig(GPIO_Remap_USART1, ENABLE); // 改变指定管脚脚的映射Changes the mapping of the specified pin/* Con figure USART1 RTS (PA12) and USART1 Tx (PA9) as alternate fun ctio n push-pull 根据资料可查得各管脚对应*/GPIO_I ni tStructure.GPIO_Pin =GPIO_P in_9;GPIO_I nitStructure.GPIO_Speed = GPIO_Speed_5OMH z;GPIO_I nitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 推挽输出GPIO_I nit(GPIOA, & GPIO_I nitStructure);/* Con figure USART2 CTS (PA11) and USART1 Rx (PA10) as in put floati ng */GPIO_I ni tStructure.GPIO_Pin =GPIO_P in_10;GPIO_I ni tStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_I nit(GPIOA, & GPIO_I nitStructure);GPIO_I ni tStructure.GPIO_P in=GPIO_Pin_1|GPIO_Pin_O|GPIO_Pin_2|GPIO_Pin_3;GPIO_I nitStructure.GPIO_Speed=GPIO_Speed_5OMH z;GPIO_I ni tStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_I nit(GPIOE,&GPIO_I nitStructure);}中断函数:(可在stm32f10x_.it.c中调用)void USART1_IRQHa ndler(void){u8 RX_dat; // 定义字符变量if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 判断发生接收中断{GPIO_WriteBit(GPIOE, GPIO_Pin_1, (BitActio n)0x01); //LED MRX_dat=(USART_ReceiveData(USART1) & 0x7F); // 接收数据,整理除去前两位USART_ClearITPe ndi ngBit(USART1, USART_IT_RXNE); 〃清除中断标志while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}〃等待接收结束// USART_ITC on fig(USART1, USART_IT_RXNE, DISABLE); // 关中断USART_Se ndData(USART1,RX_dat); 〃发送数据GPIO_WriteBit(GPIOE, GPI0_Pin_2, (BitActio n)0x01);//LED M }}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM8S105发送完成中断
#define TXRXBUF_SIZE 128
uchar UART_RxTx[TXRXBUF_SIZE];
volatile uchar UART_OutLen=0;
volatile uchar TXRX_IndexR=0;
volatile uchar TXRX_IndexW=0;
void UART2_Init(void)
{
//485 CS1控制
PA_DDR |=1 << 6;
PA_CR1 |=1 << 6;
PA_CR2 &= ~( 1 <<6 );
RS485_TX_EN=0; //设置为接收模式
UART2_CR1=0x00;
UART2_CR2=0x00;
UART2_CR3=0x00;
// 设置波特率,必须注意以下几点:
// (1) 必须先写BRR2
// (2) BRR1存放的是分频系数的第11位到第4位,
// (3) BRR2存放的是分频系数的第15位到第12位,和第3位
// 到第0位
// 例如对于波特率位9600时,分频系数=2000000/9600=208
// 对应的十六进制数为00D0,BBR1=0D,BBR2=00
//UART2_BRR2=0x30;
//UART2_BRR1=0xE8; //1K
//UART2_BRR2=0x35;
//UART2_BRR1=0x41; //1200
UART2_BRR2=0x1B;
UART2_BRR1=0xA0; //2400
UART2_CR2=0x2c;//允许接收,发送,开接收中断
//UART2_CR2=0x08; //发送使能
}
//------------方式二发送结束中断--------------------------------------
#pragma vector=UART2_T_TC_vector
__interrupt void UART2_T_TC(void)
{
UART2_SR&= ~(1<<6); //清除送完成状态位
if(UART_OutLen>0)
{
UART2_DR=UART_RxTx[TXRX_IndexR];
--UART_OutLen;
if(++TXRX_IndexR >= TXRXBUF_SIZE)
{
TXRX_IndexR=0;//FIFO回头
}
}
else //发送结束
{
//UART_OutLen=TXRX_IndexR=TXRX_IndexW=0;
//UART2_CR2 &= ~(1<<TCIEN);//关闭发送完成中断
UART2_CR2 &= ~(1<<6);//关闭发送完成中断
}
}
/***********************************************************
*名称:Uart_IntSentBuf
*功能:从串口UART0发送一组字节数据
*入口参数:*p:待发的首个字节数据,len 发送个数
*出口参数:返回1:发送成功
* 返回0:发送失败
*说明:在发送过程中,不阻塞CPU的运行。
函数口中包含了两种中断发送方式,可选择
***********************************************************/
u8 Uart_IntSentBuf(u8 *p,u8 len)
{
u8 i;
if (len <= (TXRXBUF_SIZE-UART_OutLen))//缓存区空间不小于发送字节数
{
/*
//------------方式一缓冲空中断--------------------------------------
if(!(UART2_CR2&(1<<TIEN))) //缓冲空中断关
{
UART_OutLen=TXRX_IndexR=TXRX_IndexW=0;
}
else
{
UART2_CR2 &= ~(1<<TIEN);//关发送中断
}
for ( i=0;i<len;i++)
{
UART_OutLen++;//发送字节数
UART_RxTx[TXRX_IndexW]=*p++;//移入FIFO数据
if(++TXRX_IndexW >= TXRXBUF_SIZE)
{
TXRX_IndexW=0;//FIFO回头
}
}
if(UART2_SR&(1<<TXE)) //发送缓冲区为空
UART2_SR|=(1<<TXE); //写1与UDRIE 产生空中断UART2_CR2 |= (1<<TIEN); //开发送缓冲中断
//----------------------end 方式一------------------------------------ */
/*
//------------方式二发送结束中断-------------------------------------- if(!(UART2_CR2&(1<<TCIEN)))
{
UART_OutLen=TXRX_IndexR=TXRX_IndexW=0;
for ( i=0;i<len;i++)
{
UART_OutLen++;//发送字节数
UART_RxTx[TXRX_IndexW]=*p++;//移入FIFO数据
if(++TXRX_IndexW >= TXRXBUF_SIZE)
{
TXRX_IndexW=0;//FIFO回头
}
}
if(UART2_SR&(1<<TC)) //发送完毕
UART2_SR&= ~(1<<TC); //写1清除送完成状态位UART2_CR2 |= (1<<TCIEN);//开发送完成中断
UART2_DR=UART_RxTx[TXRX_IndexR];
--UART_OutLen;
++TXRX_IndexR;
}
else
{
UART2_CR2 &= ~(1<<TCIEN);//关闭发送完成中断
for ( i=0;i<len;i++)
{
UART_OutLen++;//发送字节数
UART_RxTx[TXRX_IndexW]=*p++;//移入FIFO数据
if(++TXRX_IndexW >= TXRXBUF_SIZE)
{
TXRX_IndexW=0;//FIFO回头
}
}
UART2_CR2 |= (1<<TCIEN);//开发送完成中断
}
//----------------------end 方式二------------------------------------ */
//------------方式二发送结束中断-------------------------------------- if(!(UART2_CR2&(1<<6)))
{
UART_OutLen=TXRX_IndexR=TXRX_IndexW=0;
for ( i=0;i<len;i++)
{
UART_OutLen++;//发送字节数
UART_RxTx[TXRX_IndexW]=*p++;//移入FIFO数据
if(++TXRX_IndexW >= TXRXBUF_SIZE)
{
TXRX_IndexW=0;//FIFO回头
}
}
if(UART2_SR&(1<<6)) //发送完毕
UART2_SR&= ~(1<<6); //清除送完成状态位
UART2_CR2 |= (1<<6);//开发送完成中断
UART2_DR=UART_RxTx[TXRX_IndexR];
--UART_OutLen;
++TXRX_IndexR;
}
else
{
UART2_CR2 &= ~(1<<6);//关闭发送完成中断
for ( i=0;i<len;i++)
{
UART_OutLen++;//发送字节数
UART_RxTx[TXRX_IndexW]=*p++;//移入FIFO数据
if(++TXRX_IndexW >= TXRXBUF_SIZE)
{
TXRX_IndexW=0;//FIFO回头
}
}
UART2_CR2 |= (1<<6);//开发送完成中断
}
//----------------------end 方式二------------------------------------
return 1;
}
else
return 0;
}。