Freescale 9S12 系列单片机应用笔记(SCI)1
SCI模块应用笔记(1)
UART,也就是异步串行通讯接口是单片机中最常见的外设,几乎每种类型的单片机都必备1到2个UART接口,9S12系列单片机也不例外。不过,摩托罗拉给他自己的单片机的串口起了个很有个性的缩写名称SCI(serialcommunicationinterface),其实就是我们常说的UART。
本文引用地址:https://www.eepw.com.cn/article/201611/318823.htm各种单片机串口的编程都大同小异,无非就是设置波特率、起始位、停止位、校验位等等。下面通过给出编程例子的方式分别介绍。
设置波特率
- /**
- *SettheBaudRateoftheSCI.
- *@paramport,portcanbeSCI0/SCI1
- *@parambaudRate,thewantedbaudrate.
- *@parambusClk,TheSCImoduleclock.
- */
- voidSCISetBaudRate(unsignedcharport,unsignedlongbaudRate,unsignedlongbusClk)
- {
- unsignedshortbaudRateReg;
- baudRateReg=(unsignedshort)(busClk/baudRate/16);
- if(port==SCI0)
- {
- //HerewemustwriteBDHfirst!
- SCI0BDH=(0x1f&(baudRateReg>>8));
- SCI0BDL=(0xff&baudRateReg);
- }
- elseif(port==SCI1)
- {
- SCI1BDH=(0x1f&(baudRateReg>>8));
- SCI1BDL=(0xff&baudRateReg);
- }
- else
- {
- //Somethingmustgowrong.Donothinghere!
- }
- }
设置奇偶校验位
- /**
- *Enable/DisableparityfunctionandsettheParitytype
- *@paramportportcanbeSCI0/SCI1
- *@paramisEnable0fordisableparityfunction,1forenable
- *@paramtype0forEvenParity,1forOddParity
- */
- voidSCISetParity(unsignedcharport,unsignedcharisEnable,unsignedchartype)
- {
- if(port==SCI0)
- {
- SCI0CR1_PE=(isEnable&0x01);
- SCI0CR1_PT=(type&0x01);
- }
- elseif(port==SCI1)
- {
- SCI1CR1_PE=(isEnable&0x01);
- SCI1CR1_PT=(type&0x01);
- }
- else
- {
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- }
- }
使能数据位的长度
- /**
- *SettheDataFormatModeBit
- *@paramportportcanbeSCI0/SCI1
- *@parambitsmustbe8or9
- */
- voidSCISetDataBit(unsignedcharport,unsignedcharbits)
- {
- if(port==SCI0)
- {
- switch(bits)
- {
- case8:
- SCI0CR1_M=0;/*1startbit,8databits,1stopbit*/
- break;
- case9:
- SCI0CR1_M=1;/*1startbit,9databits,1stopbit*/
- break;
- default:
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- break;
- }
- }
- elseif(port==SCI1)
- {
- switch(bits)
- {
- case8:
- SCI1CR1_M=0;/*1startbit,8databits,1stopbit*/
- break;
- case9:
- SCI1CR1_M=1;/*1startbit,9databits,1stopbit*/
- break;
- default:
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- break;
- }
- }
- else
- {
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- }
- }
设置串口的工作模式
NORMAL_MODE是我们通常用的模式
LOOP_MODE是自发自收模式
SING_WIRE_MODE就是收发公用一条数据线的模式
- /**
- *Settheworkmodeofoperation
- *@paramportportcanbeSCI0/SCI1
- *@parammodemodecanbeNORMAL_MODE/LOOP_MODE/SING_WIRE_MODE
- */
- voidSCISetWorkMode(unsignedcharport,unsignedcharmode)
- {
- if(port==SCI0)
- {
- switch(mode)
- {
- caseNORMAL_MODE:
- SCI0CR1_LOOPS=0;
- SCI0CR1_RSRC=0;
- break;
- caseLOOP_MODE:
- SCI0CR1_LOOPS=1;
- SCI0CR1_RSRC=0;
- break;
- caseSING_WIRE_MODE:
- SCI0CR1_LOOPS=1;
- SCI0CR1_RSRC=1;
- break;
- default:
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- break;
- }
- }
- elseif(port==SCI1)
- {
- switch(mode)
- {
- caseNORMAL_MODE:
- SCI1CR1_LOOPS=0;
- SCI1CR1_RSRC=0;
- break;
- caseLOOP_MODE:
- SCI1CR1_LOOPS=1;
- SCI1CR1_RSRC=0;
- break;
- caseSING_WIRE_MODE:
- SCI1CR1_LOOPS=1;
- SCI1CR1_RSRC=1;
- break;
- default:
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- break;
- }
- }
- else
- {
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- }
- }
设置SCI模块是否在Wait模式下工作
- /**
- *Enable/DisabletheSCIinwaitmode
- *@paramportportcanbeSCI0/SCI1
- *@parammodemodecanbeRUN_MODE/WAIT_MODE
- */
- voidSCISetPowerMode(unsignedcharport,unsignedcharmode)
- {
- if(port==SCI0)
- {
- switch(mode)
- {
- caseRUN_MODE:
- SCI0CR1_SCISWAI=0;
- break;
- caseWAIT_MODE:
- SCI0CR1_SCISWAI=1;
- break;
- default:
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- break;
- }
- }
- elseif(port==SCI1)
- {
- switch(mode)
- {
- caseRUN_MODE:
- SCI1CR1_SCISWAI=0;
- break;
- caseWAIT_MODE:
- SCI1CR1_SCISWAI=1;
- break;
- default:
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- break;
- }
- }
- else
- {
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- }
- }
使能SCI模块的接收功能
- /**
- *Enable/DisableSCIReceiver
- *@paramportportcanbeSCI0/SCI1
- *@paramisEnable0disable1enable
- */
- voidSCIEnableRecv(unsignedcharport,unsignedcharisEnable)
- {
- if(port==SCI0)
- {
- SCI0CR2_RE=(isEnable&0x01);
- }
- elseif(port==SCI1)
- {
- SCI1CR2_RE=(isEnable&0x01);
- }
- else
- {
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- }
- }
使能SCI模块的发送功能
- /**
- *Enable/DisableSCITransmitter
- *@paramportportcanbeSCI0/SCI1
- *@paramisEnable0disable1enable
- */
- voidSCIEnableTrans(unsignedcharport,unsignedcharisEnable)
- {
- if(port==SCI0)
- {
- SCI0CR2_TE=(isEnable&0x01);
- }
- elseif(port==SCI1)
- {
- SCI1CR2_TE=(isEnable&0x01);
- }
- else
- {
- //Ifcoderunhere,somethingmustgowrong.Donothinghere!
- }
- }
发送数据
- /**
- *SendacharthrounghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramsthedatatobesent
- */
- voidSCIPutChar(unsignedcharport,unsignedchars)
- {
- if(port==SCI0)
- {
- while(SCI0SR1_TDRE==0);//SCI0SR1_TC是发送完成
- SCI0DRL=s;
- }
- else
- {
- while(SCI1SR1_TDRE==0);//SCI1SR1_TC
- SCI1DRL=s;
- }
- }
- /**
- *SendacharstringthrounghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@param*strthestringtobesent
- */
- voidSCIPutStr(unsignedcharport,unsignedchar*str)
- {
- while(0!=*str)
- {
- SCIPutChar(port,*str);
- str++;
- }
- }
- /**
- *SenddatathrounghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@param*ppointertothedatatobesent
- *@paramsizethesize(byte)ofthedata
- */
- voidSCIWrite(unsignedcharport,void*p,intsize)
- {
- unsignedchar*str=(unsignedchar*)p;
- while(size>0)
- {
- SCIPutChar(port,*str);
- str++;
- size--;
- }
- }
- /**
- *Sendashortintvalue(BigEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutShortBigEndian(unsignedcharport,shorti)
- {
- char*p=(char*)&i;
- SCIPutChar(port,p[0]);
- SCIPutChar(port,p[1]);
- }
- /**
- *Sendashortintvalue(LittleEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutShortLittleEndian(unsignedcharport,shorti)
- {
- char*p=(char*)&i;
- SCIPutChar(port,p[1]);
- SCIPutChar(port,p[0]);
- }
- /**
- *Sendalongintvalue(BigEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutLongBigEndian(unsignedcharport,longi)
- {
- char*p=(char*)&i;
- SCIPutChar(port,p[0]);
- SCIPutChar(port,p[1]);
- SCIPutChar(port,p[2]);
- SCIPutChar(port,p[3]);
- }
- /**
- *Sendalongintvalue(LittleEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutLongLittleEndian(unsignedcharport,longi)
- {
- char*p=(char*)&i;
- SCIPutChar(port,p[3]);
- SCIPutChar(port,p[2]);
- SCIPutChar(port,p[1]);
- SCIPutChar(port,p[0]);
- }
接收数据
- /**
- *ReceiveachardatafromSCImodule,noreply.
- *@paramportportcanbeSCI0/SCI1
- *@returnthereceivedchar
- */
- unsignedcharSCIGetChar(unsignedcharport)
- {
- if(port==SCI0)
- {
- while(SCI0SR1_RDRF==0);
- returnSCI0DRL;
- }
- else
- {
- while(SCI1SR1_RDRF==0);
- returnSCI1DRL;
- }
- }
相应的头文件
- /**
- *filesci.h
- *authorLiYuan
- *platform:mc9s12dp256B
- *date:2012-4-16
- *version:1.0.0
- *description:SCI(SerialCommunicationInterface)SupportCode
- */
- #ifndef_SCI_H_
- #define_SCI_H_
- #defineSCI00
- #defineSCI11
- #defineIDLE_LINE0
- #defineADDRESS_MARK1
- #defineNORMAL_MODE0
- #defineLOOP_MODE1
- #defineSING_WIRE_MODE2
- #defineRUN_MODE0
- #defineWAIT_MODE1
- /*FunctionDeclaration*/
- /**
- *SettheBaudRateoftheSCI.
- *@paramport,portcanbeSCI0/SCI1
- *@parambaudRate,thewantedbaudrate.
- *@parambusClk,TheSCImoduleclock.
- */
- voidSCISetBaudRate(unsignedcharport,unsignedlongbaudRate,unsignedlongbusClk);
- /**
- *SettheInterruptEnableBit
- *@paramportportcanbeSCI0/SCI1
- *@paramtieTransmitterInterruptEnableBIt
- *@paramtcieTransmissionCompleteInterruptEnableBIt
- *@paramrieReceiverFullInterruptEnableBIt
- *@paramilieIdleLineInterruptEnableBIt
- *0InterruptrequestsDisabled
- *1InterruptrequestsEnabled
- */
- voidSCISetIEBit(unsignedcharport,unsignedchartie,unsignedchartcie,unsignedcharrie,unsignedcharilie);
- /**
- *EnableTheTxinterrupt(TransmitterInterruptEnableBIt)
- *@paramport,portcanbeSCI0/SCI1
- */
- voidSCIEnableTxInt(unsignedcharport);
- /**
- *DisableTheTxinterrupt(TransmitterInterruptEnableBIt)
- *@paramport,portcanbeSCI0/SCI1
- */
- voidSCIDisTxInt(unsignedcharport);
- /**
- *Enable/DisableSCIReceiver
- *@paramportportcanbeSCI0/SCI1
- *@paramisEnable0disable1enable
- */
- voidSCIEnableRecv(unsignedcharport,unsignedcharisEnable);
- /**
- *Enable/DisableSCITransmitter
- *@paramportportcanbeSCI0/SCI1
- *@paramisEnable0disable1enable
- */
- voidSCIEnableTrans(unsignedcharport,unsignedcharisEnable);
- /**
- *SettheIdleLineType
- *@paramportportcanbeSCI0/SCI1
- *@paramtype0Idlecharbitcountbeginsafterstartbit
- *1Idlecharbitcountbeginsafterstopbit
- */
- voidSCISetIdleLineType(unsignedcharport,unsignedchartype);
- /**
- *SettheWakeupCondition.
- *@paramportportcanbeSCI0/SCI1
- *@paramcondi0forIdlelinewakeup,1foraddressmarkwakeup
- */
- voidSCISetWakeupCondi(unsignedcharport,unsignedcharcondi);
- /**
- *Enable/DisableparityfunctionandsettheParitytype
- *@paramportportcanbeSCI0/SCI1
- *@paramisEnable0fordisableparityfunction,1forenable
- *@paramtype0forEvenParity,1forOddParity
- */
- voidSCISetParity(unsignedcharport,unsignedcharisEnable,unsignedchartype);
- /**
- *SettheDataFormatModeBit
- *@paramportportcanbeSCI0/SCI1
- *@parambitsmustbe8or9
- */
- voidSCISetDataBit(unsignedcharport,unsignedcharbits);
- /**
- *Settheworkmodeofoperation
- *@paramportportcanbeSCI0/SCI1
- *@parammodemodecanbeNORMAL_MODE/LOOP_MODE/SING_WIRE_MODE
- */
- voidSCISetWorkMode(unsignedcharport,unsignedcharmode);
- /**
- *Enable/DisabletheSCIinwaitmode
- *@paramportportcanbeSCI0/SCI1
- *@parammodemodecanbeRUN_MODE/WAIT_MODE
- */
- voidSCISetPowerMode(unsignedcharport,unsignedcharmode);
- /**
- *SettheTXDIR(OnlyforSingleWireMODE)
- *@paramportportcanbeSCI0/SCI1
- *@paramdir0TXDusedasinput,1TXDusedasoutput
- */
- voidSCISetTXDIR(unsignedcharport,unsignedchardir);
- /**
- *SendacharthrounghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramsthedatatobesent
- */
- voidSCIPutChar(unsignedcharport,unsignedchars);
- /**
- *ReceiveachardatafromSCImodule,noreply.
- *@paramportportcanbeSCI0/SCI1
- *@returnthereceivedchar
- */
- unsignedcharSCIGetChar(unsignedcharport);
- /**
- *Sendashortintvalue(BigEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutShortBigEndian(unsignedcharport,shorti);
- /**
- *Sendashortintvalue(LittleEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutShortLittleEndian(unsignedcharport,shorti);
- /**
- *Sendalongintvalue(BigEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutLongBigEndian(unsignedcharport,longi);
- /**
- *Sendalongintvalue(LittleEndian)throunghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@paramithedatatobesent
- */
- voidSCIPutLongLittleEndian(unsignedcharport,longi);
- /**
- *SendacharstringthrounghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@param*strthestringtobesent
- */
- voidSCIPutStr(unsignedcharport,unsignedchar*str);
- /**
- *SenddatathrounghSCImodule.
- *@paramportportcanbeSCI0/SCI1
- *@param*ppointertothedatatobesent
- *@paramsizethesize(byte)ofthedata
- */
- voidSCIWrite(unsignedcharport,void*p,intsize);
- #endif
下面给个简单的例子
- #include
/*commondefinesandmacros*/ - #include"derivative.h"/*derivative-specificdefinitions*/
- #include"sci.h"
- voidmain(void)
- {
- charC;
- EnableInterrupts;
- SCISetWorkMode(SCI0,NORMAL_MODE);
- SCISetPowerMode(SCI0,RUN_MODE);
- SCISetBaudRate(SCI0,9600,16384000L);//16MClock
- SCISetDataBit(SCI0,8);
- SCISetParity(SCI0,0,0);
- SCIEnableRecv(SCI0,1);
- SCIEnableTrans(SCI0,1);
- for(;;)
- {
- _FEED_COP();/*feedsthedog*/
- C=SCIGetChar(SCI0);
- SCIPutChar(SCI0,C);
- }/*loopforever*/
- /*pleasemakesurethatyouneverleavemain*/
- }
先写这么多,剩下的明天继续。下一篇笔记中将给出如何利用串口的收发中断和环形缓冲区来实现较为完善的串口驱动。
评论