1.内核时钟设置SysCtlClockSet
2.片上设备时钟使能SysCtlPeripheralEnable
3.GPIO设置GPIODirModeSet/Get
// Param3:1.输入(数字、模拟)
2.输出(数字)
3.硬件决定(数字第二功能)
GPIOPadConfigSet/Get
// Param2:1.驱动强度(数字、模拟)
// Param3:1.推挽/开漏(数字) 2.模拟功能(模拟)
注:上述两个函数被封装成了以下函数做简化GPIOPinTypeGPIOInput //输入、2mA、推挽_GPIO
GPIOPinTypeGPIOOnput //输出、2m、推挽_GPIO GPIOPinTypeGPIOOutputOD //输出、2mA、开漏_GPIO GPIOPinTypeADC //输入、2mA、模拟_ADC GPIOPinTypeComparator //输入、2mA、模拟_比较器
GPIOPinTypeCAN //硬件、8mA、推挽_CAN GPIOPinTypeEthernetLED //硬件、8mA、推挽_以太网LED GPIOPinTypeI2C //硬件、2mA、开漏弱上拉_I2C GPIOPinTypeI2S //硬件、2mA、推挽_I2S
GPIOPinTypePWM //硬件、2mA、推挽_PWM GPIOPinTypeQEI //硬件、2mA、推挽弱上拉_QEI GPIOPinTypeSSI //硬件、2mA、推挽_SSI
GPIOPinTypeTimer //硬件、2mA、推挽_Timer GPIOPinTypeUART //硬件、2mA、推挽_Uart GPIOPinTypeUSBDigital //硬件、2mA、推挽_USB
4 IO口读写
GPIOPinRead/Write //Pin数据读写
GPIO用作中断的操作流程
1.系统时钟配置SysCtlClockSet
2.GPIO设备时钟打开SysCtlPeripheralEnable
3.Pin脚功能设置GPIOPinTypeInput
4.Pin脚中断触发模式设置GPIOIntTypeSet //0.片内外设中断模式配置
5.Pin脚中断允许GPIOPinIntEnable //1.使能片内外设的具体中断
6.内设中断允许IntEnable //2.使能片内外设的总中断
7.MCU总中断允许IntMasterEnable //3.使能MCU的总中断
中断服务程序
1.读取中断源GPIOPinIntStatus
2.清除中断源GPIOPinIntClear //M3的内核中断,不需要手动清除
UART的操作流程
1.系统时钟配置SysCtlClockSet
2.GPIO设备时钟打开SysCtlPeripheralEnable
3.UART设备时钟打开SysCtlPeripheralEnable
4.GPIO复用引脚设定为Tx和Rx GPIOPinTypeUART
5.1UART工作参数配置UARTConfigSetExpClk
[5.2] 若使用UART中断模式,则需配置
5.2.1 Tx和Rx引脚中断允许UARTIntEnable
5.2.2 UART功能启动UARTEnable
5.2.3 内设中断允许IntEnable
6.UART收发
6.1 Block模式:(将NoBlock模式的4个函数封装成2个)
直接发送字符UARTCharPut
直接接收字符UARTCharGet
6.2 NoBlock模式:(使用FIFO)
等待Rx_FIFO有数据UARTCharsAvail
等待Tx_FIFO有数据UARTSpaceAvail
Block发送字符UARTCharPutNonBlocking
Block接收字符UARTCharGetNonBlocking (注:使用此函数,必须先查询UARTCharsAvail)
6.3 INT模式:(中断服务函数)
UART中断清除UARTIntClear
使用Block/NoBlock模式发送和接收字符
PWM的操作流程
1.系统时钟设置SysCtlClockSet
2.PWM模块时钟设置SysCtlPWMClockSet
3.GPIO设备时钟打开SysCtlPeripheralEnable
4.PWM模块时钟打开SysCtlPeripheralEnable
5.GPIO设置为硬件指定(PWM) GPIOPinTypePWM
6.Pin脚配置为PWM功能GPIOPinConfigure
7.PWM发生器计数模式设置PWMGenConfigure
8.PWM发生器周期设置PWMGenPeriodSet
9.PWM发生器脉宽设置PWMPulseWidthSet
10.PWM输出管脚使能PWMOutputState101
11.PWM启动PWMGenEnable102 103 104 105
SysTick的操作流程
1.系统时钟设置SysCtlClockSet
2.SysTick周期设置SysTickPeriodSet//减法计数器,归零后自动重装
3.SysTick启动SysTickEnable111
4.MCU总中断开启IntMasterEnable
5.SysTick中断服务函数void SysTick_ISR() { //SysTick是系统内设,硬件自动清除中断,
无须手动清除
Timer的操作流程
32bit 定时器
32bit RTC定时器
16bit 定时器
16bit 捕获器(边沿计数:计算有几个边沿;边沿定时:计算前后边沿的时间差)
16bit PWM
1.系统时钟设置SysCtlClockSet
2.片上设备时钟使能SysCtlPeripheralEnable
3.定时器工作模式设置TimerConfigure
4.定时器载入值设置TimerLoadSet
5.定时器中断使能TimerIntEnable136
6.外设中断总使能IntEnable
7.MCU总中断使能IntMaskEnable
8.定时器启动TimerEnable140
Timer中断服务函数
void Timer_ISR() { //手工清除中断状态TimerIntClear(); ...//功能代码}
ADC操作流程1.系统时钟设置SysCtlClockSet
2.ADC所在GPIO外设时钟打开SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
3.IO口配置为ADC功能GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
4.ADC外设时钟打开SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);
5.ADC采样序列配置ADCSequenceConfigure(ADC0_BASE, 3, DC_TRIGGER_PROCESSOR, 0);
6.ADC采样序列步进配置ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); // 启动AD的采样序列发生器3 ADCSequenceEnable(ADC0_BASE, 3); // 清除中断标志ADCIntClear(ADC0_BASE, 3);
MSP430程序库<二>UART异步串口 串行通信接口是处理器与其他设备进行数据通信最常用的方式之一。我的这个程序库是针对MSP430f14系列和MSP430f16系列的,我常用的单片机是这两款:msp430f149,ms p430f169。这两款单片机中均有两个增强型串行通信接口,都可以进行同步或是异步通信,甚至169的模块USART0还能进行进行I2C协议通信。在这里,我们只讨论异步串行通信。 硬件介绍: MSP单片机的USART模块可以配置成SPI(同步通信)模式或UART(异步通信)模式,这里只讨论UART方式。UART数据传输格式如下: 起始位,数据位由高到低7/8位,地址位0/1位,奇偶校验位奇偶或无,停止位1/2位。数据位位数、地址位、奇偶校验位、停止位均可由单片机内部寄存器控制;这两款单片机都有两个USART模块,有两套独立的寄存器组;以下寄存器命中出现x代表0或是1,0代表对应0模块的寄存器,1代表对应1模块的寄存器;其中,与串口模式设置相关的控制位都位于UxCTL寄存器,与接收相关的控制位都位于UxRCTL寄存器,与发送相关的控制位都位于UxTCTL寄存器;波特率设置用UxBR0、UxBR1、UxMCT L三个寄存器;接收与发送有独立的缓存UxRXBUF、UxTXBUF,并具有独立的移位寄存器和独立的中断;中断允许控制位位于IE1/2寄存器,中断标志位位于IFG1/2寄存器。 波特率设置:430的波特率设置用三个寄存器实现, UxBR0:波特率发生器分频系数低8位。 UxBR1:波特率发生器分频系数高8位。 UxMCTL:波特率发生器分频系数的小数部分实现。 设置波特率时,首先要选择合适的时钟源:USART模块可以设置的时钟源有UCLK引脚、ACLK、SMCLK;对于较低的波特率(9600以下),可选ACLK作为时钟源,这样,在LPM3(低功耗3)模式下,串口仍能正常发送接收数据;另外,由于串口接收过程有一个三取二判决逻辑,这至少需要三个时钟周期,因此分频系数必须大于3;波特率高于9600时,将不能使用ACLK作为时钟源,要调为频率较高的SMCLK作为时钟源;另外还可以外部输入UCLK时钟。分频系数计算公式如下:
这个程序没有仿真、没有测试。。 1 UART功能设计 1.1 UART的工作原理 异步通信时,UART发送/接收数据的传输格式如图1所示,一个字符单位由开始位、数据位、停止位组成。 异步通信的一帧传输经历以下步骤: (1)无传输。发送方连续发送信号,处于信息“1”状态。 (2)起始传输。发送方在任何时刻将传号变成空号,即“1”跳变到“O”,并持续1位时间表明发送方开始传输数据。而同时,接收方收到空号后,开始与发送方同步,并期望收到随后的数据。 (3)奇偶传输。数据传输之后是可供选择的奇偶位发送或接收。 (4)停止传输。最后是发送或接收的停止位,其状态恒为“1”。 其程序的结构框图如下: 该程序的效果是串口接受到从计算机发送过来的数据后,又把数据发回给计算机,串口通信是串行的。 其uart.v为顶层文件,包含其他模块,speed_select.v文件的作用为为uart_rx.v和uart_tx.v 设置波特率。
uart.v(顶层文件) `timescale 1ns / 1ps ///////////////////////////////////////////////////////////////////// ///////////// // Company: // Engineer: // // Create Date: 16:08:27 11/12/2010 // Design Name: // Module Name: uart // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ///////////////////////////////////////////////////////////////////// ///////////// module uart(clk,rst_n,rs232_rx,rs232_tx); input clk,rst_n,rs232_rx; output rs232_tx; wire bps_start1,bps_start2,clk_bps1,clk_bps2,rx_int; wire [7:0] rx_data; //发送模块的时钟 speed_select speed_tx ( .clk(clk), .rst_n(rst_n), .bps_start(bps_start2), .clk_bps(clk_bps1) ); //接受模块的时钟 speed_select speed_rx ( .clk(clk), .rst_n(rst_n), .bps_start(bps_start2), .clk_bps(clk_bps2)
//UART实验程序解析 //头文件 #include
ROM_UARTCharGetNonBlocking(UART0_BASE)); } } //串口发送函数 void UARTSend(const ui8 *pucBuffer, ui32 ulCount) { while(ulCount--) { //将要发送的字符写进UART ROM_UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++); } } int main(void) { //使能FPU FPUEnable(); FPULazyStackingEnable(); //设置时钟直接使用外部晶振 ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //使能用到的外设 ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); //配置PA0和PA1为串口0引脚 ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
// UART_FPGA.v 顶层模块,实现由ARM控制FPGA读取串口数据,经过ARM返回给FPGA串口发送出去; `timescale 1ns/1ns module UART_FPGA( //EMIF PIN input wire [10:0] EADDR_pin /* synthesis syn_noclockbuf = 1 */, inout wire [15:0] EDATA_pin , input wire EnOE_pin /* synthesis syn_noclockbuf = 1 */, input wire EnWE_pin /* synthesis syn_noclockbuf = 1 */, input wire EnGCS1_pin /* synthesis syn_noclockbuf = 1 */, output wire EINT2_pin , //LED_run output wire LED_run_pin , //UART output wire UART_TXD0 , input wire UART_RXD0 /* synthesis syn_noclockbuf = 1 */, //test signal output wire TXD_test, output wire RXD_test, output reg TXD_start, output wire EINT2_test, output wire TXD_over_test, output wire uart_send_WR, //FPGA SYSTEM PIN input wire nRESET_pin /* synthesis syn_noclockbuf = 1 */, input wire CLK_50M_pin ); wire [15:0] write_data;
module my_uart_top( clk,rst_n, rs232_rx,rs232_tx ); input clk; lk(clk), st_n(rst_n), .bps_start(bps_start1), .clk_bps(clk_bps1) , ); my_uart_rx my_uart_rx( .clk(clk), st_n(rst_n), .rs232_rx(rs232_rx), .rx_data(rx_data), .rx_int(rx_int), .clk_bps(clk_bps1), % .bps_start(bps_start1) ); lk(clk), st_n(rst_n), .bps_start(bps_start2), .clk_bps(clk_bps2) ); ` my_uart_tx my_uart_tx( .clk(clk), st_n(rst_n), .rx_data(rx_data), .rx_int(rx_int), .rs232_tx(rs232_tx), .clk_bps(clk_bps2), .bps_start(bps_start2) ); . endmodule module my_uart_rx( clk,rst_n, rs232_rx,rx_data,rx_int, …
clk_bps,bps_start ); input clk; // 50MHz主时钟 input rst_n; //低电平复位信号 input rs232_rx; // RS232接收数据信号 input clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点 output bps_start; //接收到数据后,波特率时钟启动信号置位 ` output[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到 output rx_int; //接收数据中断信号,接收到数据期间始终为高电平 //---------------------------------------------------------------- reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3; //接收数据寄存器,滤波用 wire neg_rs232_rx; //表示数据线接收到下降沿 always @ (posedge clk or negedge rst_n) begin { if(!rst_n) begin rs232_rx0 <= 1'b0; rs232_rx1 <= 1'b0; rs232_rx2 <= 1'b0; rs232_rx3 <= 1'b0; end else begin rs232_rx0 <= rs232_rx; : rs232_rx1 <= rs232_rx0; rs232_rx2 <= rs232_rx1; rs232_rx3 <= rs232_rx2; end end //下面的下降沿检测可以滤掉<20ns-40ns的毛刺(包括高脉冲和低脉冲毛刺), //这里就是用资源换稳定(前提是我们对时间要求不是那么苛刻,因为输入信号打了好几拍) //(当然我们的有效低脉冲信号肯定是远远大于40ns的) , assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0; //接收到下降沿后neg_rs232_rx置高一个时钟周期 //---------------------------------------------------------------- reg bps_start_r; reg[3:0] num; //移位次数 reg rx_int; //接收数据中断信号,接收到数据期间始终为高电平
AN462 硬件和软件验证流程 Rev. _1 — 7 August 1987 应用规格书 文件信息 信息内容 关键词UART,软硬件验证 摘要这个流程是用于检验主机(控制处理器)、UART和印制电路板之间的信号、总线、电气连接和时序的正确性。以下流程的执行和结果的验证不需要任 何其它的测试设备(逻辑分析仪、协议分析仪,示波器等),它是基于处 理器能够读写UART,并且所得到的结果能显示给操作者的假设之上 的。如果无法完全确认简单的读写操被正确的执行,那么针对UART连 接的其它检验都是不可靠的。
1. 概述 这个流程是用于检验主机(控制处理器)、UART和印制电路板之间的信号、总线、电气连接和时序的正确性。以下流程的执行和结果的验证不需要任何其它的测试设备(逻辑分析仪、协议分析 仪,示波器等),它是基于处理器能够读写UART,并且所得到的结果能显示给操作者的假设之 上的。如果无法完全确认简单的读写操被正确的执行,那么针对UART连接的其它检验都是不可 靠的。 2. 总流程 首先,对相关的寄存器进行写和读的操作,在这些操作中与时钟有关的有片选、读、写信号; 其次,通过读取状态寄存器的值来观察所写入的几个控制寄存器的结果;接下来建议的几个流程用 于验证总线数据流并采用“本地循环回送”的模式来验证接收器和发送器的运行,“本地循环回 送”模式(所有的数据的发送和接收发生在UART内部)用于产生处理器中断或查询状态。这些流 程的正确执行将表明内部寄存器、总线接口、时钟发生器、计数器和振荡器的正常运行,没有得到 验证的是振荡器的频率、TxD和 RxD与外部端口及普通输入输出管脚的连接。 3. 注释 在硬件和软件的验证模式中,读取状态寄存器的状态是非常有效的,它对于检测那些在”已验证” 过的硬件和软件上出现的“随机”或“少见”的错误也很有效。状态的读取可以在对设备进行操作 之前和之后进行,寄存器的内容将反映异常状况发生的时间地点,这将使得UART的内部状态与外 部连接、时序、软件一样具有了可见性。例一:在硬件复位后读取状态将显示发送器空标志位置 位,这表示发送器已经使能(在硬件复位后将立即返回0x00),然而软件并没有使能发送器,因此 有人会把原因归结于:特殊的干扰,复位信号下降沿太缓慢等等,所有这些就像执行了一个发送器 使能的命令,如果这种情况确实发生,采取进一步的验证操作来修正错误的意义并不大。例二:在 对UART复位和执行几个操作之后,并且在使能接收器之前,发现有一些接收器数据状态位置位 (如奇偶校验出错),这表示接收器已经使能,并且收到数据(虽然我们并没在软件上对接收器执 行使能的命令),这可能是由于时序的冲突(可能是地址总线上的)移动了接收器FIFO的读取指针而 导致了上电后接收器FIFO的随机状态的上报。经常还出现软件的不同模块都控制UART,并且各控 制是独立的情况,这将导致更多的情况出现。 <12NC> ?Koninklijke Philips Electronics N.V. 2004. All rights reserved.应用规格书Rev. _1 — 7 August 1987 2 of 11
UART是什么?串口工作过程分析 一、UART是什么 UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器,是设备间进行异步通信的关键模块。UART负责处理数据总线和串行口之间的串/并、并/串转换,并规定了帧格式;通信双方只要采用相同的帧格式和波特率,就能在未共享时钟信号的情况下,仅用两根信号线(Rx 和Tx)就可以完成通信过程,因此也称为异步串行通信。 若加入一个合适的电平转换器,如SP3232E、SP3485,UART 还能用于RS-232、RS-485 通信,或与计算机的端口连接。UART 应用非常广泛,手机、工业控制、PC 等应用中都要用到UART。 UART使用的是异步,串行通信。串行通信是指利用一条传输线将资料一位位地顺序传送。特点是通信线路简单,利用简单的线缆就可实现通信,降低成本,适用于远距离通信,但传输速度慢的应用场合。异步通信以一个字符为传输单位,通信中两个字符间的时间间隔多少是不固定的,然而在同一个字符中的两个相邻位间的时间间隔是固定的。数据传送速率用波特率来表示,即每秒钟传送的二进制位数。例如数据传送速率为120字符/秒,而每一个字符为10位(1个起始位,7个数据位,1个校验位,1个结束位),则其传送的波特率为10×120=1200字符/秒=1200波特。数据通信格式如下图: 其中各位的意义如下:起始位:先发出一个逻辑”0”信号,表示传输字符的开始。数据位:可以是5~8位逻辑”0”或”1”。如ASCII码(7位),扩展BCD码(8位)。小端传输校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验) 停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。注:异步通信是按字符传
程序实现功能:可以直接接收USART1的数据,并通过串口调试输出显示 #include"stm32f10x_lib.h" void NVIC_Configuration(void); void RCC_Configuration(void); void GPIO_Configuration(void); ErrorStatus HSEStartUpStatus; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; int main() { #ifdef DEBUG debug #endif RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); /*串口传输速率的大小必须与RCC所设定的时钟相对应起来*/ USART_https://www.doczj.com/doc/9711035139.html,ART_BaudRate = 9600; //设置USART的传输速率/*设定数据的接收发送模式*/ USART_https://www.doczj.com/doc/9711035139.html,ART_WordLength = USART_WordLength_8b;//在一帧中传输或接受8位数据位 USART_https://www.doczj.com/doc/9711035139.html,ART_StopBits = USART_StopBits_1; //定义在帧的结尾传输一个停止位 USART_https://www.doczj.com/doc/9711035139.html,ART_Parity = USART_Parity_No; //奇偶失能 USART_https://www.doczj.com/doc/9711035139.html,ART_HardwareFlowControl = USART_HardwareFlowControl_None; //指定硬件流控制模式RTS和CTS使能 USART_https://www.doczj.com/doc/9711035139.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //指定使能或失能发送和接受模式Tx发送使能和Rx接收使能 USART_Clock https://www.doczj.com/doc/9711035139.html,ART_Clock = USART_Clock_Disable; //提升USART时钟时使能还是失能,钟低电平活动 USART_https://www.doczj.com/doc/9711035139.html,ART_CPOL = USART_CPOL_Low; //指定SLCK引脚上时钟的极性 USART_https://www.doczj.com/doc/9711035139.html,ART_CPHA = USART_CPHA_2Edge; //时钟第二个边缘进行数据捕获 USART_https://www.doczj.com/doc/9711035139.html,ART_LastBit = USART_LastBit_Disable; //在SCLK引脚上输出最后发送的那个数据字的脉冲不从SCLK输出 USART_ClockInit(USART1, &USART_ClockInitStructure); USART_Init(USART1, &USART_InitStructure); /*输入输出的中断使能*/ // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
m s p f串口程序程序 u a r t 集团标准化办公室:[VV986T-J682P28-JP266L8-68PNN]
/*****用串口助手发什么回复什么****/ #include "msp430f5529.h" // ACLK = REFO = 32768Hz, MCLK = SMCLK = default DCO/2 = 1048576Hz // P3.4,5——USCI_A0 TXD/RXD;P9.4,5——USCI_A2 TXD/RXD;P10.4,5——USCI_A3 TXD/RXD; unsigned int table[12]={1,2,3,4,5,6,7,8,9,10,11,12}; unsigned int j; void Delay(unsigned int time) { unsigned int i,k; for(i=0;i<255;i ) for(k=0;k