上级目录TMS320F28335使用教程
commonly known as a UART(通常被称为UART)
首先了解一下关于SCI的大致框图
开发板电路
本次使用SCI-A口,外部接口232,通过232转usb然后用电脑串口助手接收数据。
开发板电路:
GPIO28——rx
GPIO29——tx
单片机SCI外设配置
基本收发功能
实现通过串口助手发送数据到单片机,单片机返回相同数据的功能
首先使能外设时钟
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
GPIO配置
首先需要设置GPIO28\GPIO29为SCI外设功能
GPAMUX2的对对应为设置:
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // Configure GPIO28 for SCIRXDA operation
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // Configure GPIO29 for SCITXDA operation
SCI寄存器
接下来结合官方提供的头文件了解一下关于SCI外设的寄存器:
//---------------------------------------------------------------------------
// SCI Register File:
//
struct SCI_REGS {
union SCICCR_REG SCICCR; // Communications control register
union SCICTL1_REG SCICTL1; // Control register 1
Uint16 SCIHBAUD; // Baud rate (high) register
Uint16 SCILBAUD; // Baud rate (low) register
union SCICTL2_REG SCICTL2; // Control register 2
union SCIRXST_REG SCIRXST; // Recieve status register
Uint16 SCIRXEMU; // Recieve emulation buffer register
union SCIRXBUF_REG SCIRXBUF; // Recieve data buffer
Uint16 rsvd1; // reserved
Uint16 SCITXBUF; // Transmit data buffer
union SCIFFTX_REG SCIFFTX; // FIFO transmit register
union SCIFFRX_REG SCIFFRX; // FIFO recieve register
union SCIFFCT_REG SCIFFCT; // FIFO control register
Uint16 rsvd2; // reserved
Uint16 rsvd3; // reserved
union SCIPRI_REG SCIPRI; // FIFO Priority control
};
//对其寄存器SCICCR举例,后面每个寄存器基本都是同样的结构
union SCICCR_REG {
Uint16 all;
struct SCICCR_BITS bit;
};
//----------------------------------------------------------
// SCICCR communication control register bit definitions:
//
struct SCICCR_BITS { // bit description
Uint16 SCICHAR:3; // 2:0 Character length control
Uint16 ADDRIDLE_MODE:1; // 3 ADDR/IDLE Mode control
Uint16 LOOPBKENA:1; // 4 Loop Back enable
Uint16 PARITYENA:1; // 5 Parity enable
Uint16 PARITY:1; // 6 Even or Odd Parity
Uint16 STOPBITS:1; // 7 Number of Stop Bits
Uint16 rsvd1:8; // 15:8 reserved
};
结合数据手册每个寄存器的功能,对SCI外设进行相应的设置:
SCICCR; // Communications control register
SCICCR defines the character format, protocol, and communications mode used by the SCI
//SCICCR
union SCICCR_REG {
Uint16 all;
struct SCICCR_BITS bit;
};
//----------------------------------------------------------
// SCICCR communication control register bit definitions:
//
struct SCICCR_BITS { // bit description
Uint16 SCICHAR:3; // 2:0 Character length control
Uint16 ADDRIDLE_MODE:1; // 3 ADDR/IDLE Mode control
Uint16 LOOPBKENA:1; // 4 Loop Back enable
Uint16 PARITYENA:1; // 5 Parity enable
Uint16 PARITY:1; // 6 Even or Odd Parity
Uint16 STOPBITS:1; // 7 Number of Stop Bits
Uint16 rsvd1:8; // 15:8 reserved
};
配置:
SciaRegs.SCICCR.bit.SCICHAR = 7; // 8位数据位 Character length control
SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0; // IDLE模式 ADDR/IDLE Mode control
SciaRegs.SCICCR.bit.LOOPBKENA = 0; // 不启用回路测试 Loop Back enable
SciaRegs.SCICCR.bit.PARITYENA = 0; // 无校验 Parity enable
SciaRegs.SCICCR.bit.PARITY = 0; // 选择无校验后这一位不起作用 Even or Odd Parity
SciaRegs.SCICCR.bit.STOPBITS = 0; // 1位停止位 Number of Stop Bits
上面因为是在一个寄存器中,所以可以一次性赋值如下:
SciaRegs.SCICCR.all =0x0007;
SCICTL1; // Control register 1
SCICTL1 controls the receiver/transmitter enable, TXWAKE and SLEEP functions, and the SCI software
reset
//-------------------------------------------
// SCICTL1 control register 1 bit definitions:
//
struct SCICTL1_BITS { // bit description
Uint16 RXENA:1; // 0 SCI receiver enable
Uint16 TXENA:1; // 1 SCI transmitter enable
Uint16 SLEEP:1; // 2 SCI sleep
Uint16 TXWAKE:1; // 3 Transmitter wakeup method
Uint16 rsvd:1; // 4 reserved
Uint16 SWRESET:1; // 5 Software reset
Uint16 RXERRINTENA:1; // 6 Recieve interrupt enable
Uint16 rsvd1:9; // 15:7 reserved
};
union SCICTL1_REG {
Uint16 all;
struct SCICTL1_BITS bit;
};
配置:
SciaRegs.SCICTL1.RXENA = 1; // 接受使能 SCI receiver enable
SciaRegs.SCICTL1.TXENA = 1; // 发送使能 SCI transmitter enable
SciaRegs.SCICTL1.SLEEP = 0; // 关闭 根据SCICCR上bit3决定 SCI sleep
SciaRegs.SCICTL1.TXWAKE = 0; // 不选择传输功能 根据SCICCR上bit3决定 Transmitter wakeup method
SciaRegs.SCICTL1.SWRESET = 0; // 先写0,使用时再配置为1
// Software reset:Writing a 0 to this bit initializes the SCI
// state machinesand operating flags (registers
// SCICTL2 and SCIRXST) to the reset condition.
// After a system reset, re-enable the SCI by
// writing a 1 to this bit.
SciaRegs.SCICTL1.RXERRINTENA = 0; // 不使用接受错误标志 Recieve interrupt enable
一次性赋值如下:
SciaRegs.SCICTL1.all =0x0003;
波特率计算
LSPCLK参考:此处LSPCLK=37.5mhz
TMS320F28335时钟和系统控制
BRR=37500000/(9600*8)-1=487.28约为487=0x1E7,所以波特率寄存器高为0x01,低为0xE7
SCIHBAUD; // Baud rate (high) register
SCILBAUD; // Baud rate (low) register
SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz.
SciaRegs.SCILBAUD =0x00E7;
SCICTL2; // Control register 2
SCICTL2 enables the receive-ready, break-detect, and transmit-ready interrupts as well as transmitterready and -empty flags.
// SCICTL2 control register 2 bit definitions:
//
struct SCICTL2_BITS { // bit description
Uint16 TXINTENA:1; // 0 Transmit interrupt enable
Uint16 RXBKINTENA:1; // 1 Receiver-buffer break enable
Uint16 rsvd:4; // 5:2 reserved
Uint16 TXEMPTY:1; // 6 Transmitter empty flag
Uint16 TXRDY:1; // 7 Transmitter ready flag
Uint16 rsvd1:8; // 15:8 reserved
};
union SCICTL2_REG {
Uint16 all;
struct SCICTL2_BITS bit;
};
配置:
SciaRegs.SCICTL2.TXINTENA = 0; // 关闭接收中断 Transmit interrupt enable
SciaRegs.SCICTL2.RXBKINTENA = 0; // 关中断 Receiver-buffer break enable
SciaRegs.SCICTL2.TXEMPTY = 0; // 6 0h (R/W) = Transmitter buffer or shift register or both are loaded with data
SciaRegs.SCICTL2.TXRDY = 0; // 系统会自动置一 Transmitter ready flag
一次性赋值:
SciaRegs.SCICTL2.all =0;
配置到此结束;
总结程序:
void scia_databack_init()
{
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all =0;
SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz.
SciaRegs.SCILBAUD =0x00E7;
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
void InitSciaGpio()
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // Enable pull-up for GPIO28 (SCIRXDA)
GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0; // Enable pull-up for GPIO29 (SCITXDA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;// Asynch input GPIO28 (SCIRXDA)
/* Configure SCI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SCI functional pins.
GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // Configure GPIO28 for SCIRXDA operation
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1; // Configure GPIO29 for SCITXDA operation
EDIS;
}
void scia_xmit(int a)//发送字节的函数
{
while (SciaRegs.SCICTL2.bit.TXRDY == 0) {}//查询发送就绪标志位,发送未准备好在此循环等待
SciaRegs.SCITXBUF=a;
}
for(;;)
{
while(SciaRegs.SCIRXST.bit.RXRDY !=1) { } //等待从上位机收到数据,等于0说明没有数据到来
ReceivedChar = SciaRegs.SCIRXBUF.all;//把接收BUF里的数据赋值给ReceivedChar
//程序中间不要添加其他程序,否则会只有部分数据能回传到电脑。
//原因:程序不是使用中断接收数据,如果加入其他程序会耽误接
//受数据,造成只能接收到部分数据
scia_xmit(ReceivedChar); //发送ReceivedChar
}
实验现象:
SCIA接收中断
在基本收发功能上增加接收中断
关于中断配置参考TMS320F28335(DSP28335),中断
step1
//
// EnableInterrupts - This function enables the PIE module and CPU interrupts
//
void EnableInterrupts()
{
//
// Enable the PIE
//
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
//
// Enables PIE to drive a pulse into the CPU
//
PieCtrlRegs.PIEACK.all = 0xFFFF;//写1清除对应中断组响应标记,只有12个中断线,其余位写1没影响
//
// Enable Interrupts at the CPU level
//
EINT;
// 使用SCIA接收中断举例,SCIA接收中断为INT9.1,即第九组中断的第一个中断
//(对应中断需要查看技术手册,根据PIE中断向量表确定中断是第几组第几个)
PieCtrlRegs.PIEIER9.all = 0xFF;//第九组PIE中断使能,只有INT9.1-INT9.8
IER|=M_INT9;//使能cpu级别中断对应的中断线
}
step2
void scia_init()
{
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
//SciaRegs.SCICTL2.all =0; //关闭接收发送中断
SciaRegs.SCICTL2.all =2; //开启SCIA接收中断
SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz.
SciaRegs.SCILBAUD =0x00E7;
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
step3
//
// SCIRXINTA_ISR - INT9.1
//
interrupt void
SCIRXINTA_ISR(void) // SCI-A
{
//
// Insert ISR Code here
//
TestSciRXINT_loopback();//中断服务子程序
//
// To receive more interrupts from this PIE group, acknowledge this
// interrupt
//可以直接把对应组赋值给PIEACK.all,例如PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
//PIEACK_GROUP9是在DSP2833x_DefaultIsr.c文件中宏定义的
//PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;//这种方式可以
PieCtrlRegs.PIEACK.bit.ACK9 = 1;//写入1清除响应标志,也可以直接在对应位写入1,注意,是写1清除响应标志
//
// Next two lines for debug only to halt the processor here
// Remove after inserting ISR Code
//
// asm (" ESTOP0");
// for(;;);
}
//测试中断,用于放在中断服务程序中的发送函数
void TestSciRXINT_loopback()
{
Uint16 ReceivedChar;
ReceivedChar = SciaRegs.SCIRXBUF.all;
scia_xmit(ReceivedChar);
}
主程序:
//测试接收中断函数
void TestSciRXINT()
{
//在其他函数中时钟使能
// Uint16 ReceivedChar;
InitSciaGpio();
scia_init();//这个函数中控制sci是否开中断。现在是开接收中断
for(;;)
{
delay_loop();
scia_xmit(90); //不停发送字符Z
}
}
实验现象
关于后面的状态位,FIFO等,后续用到再继续补充