SCI模块使用笔记(1)
UART,也便是异步串行通讯接口是单片机中最常见的外设,简直每种类型的单片机都必备1到2个UART接口,9S12系列单片机也不破例。不过,摩托罗拉给他自己的单片机的串口起了个很有特性的缩写称号SCI(serialcommunicationinterface),其实便是咱们常说的UART。
各种单片机串口的编程都迥然不同,无非便是设置波特率、开始位、中止位、校验位等等。下面经过给出编程比如的方法别离介绍。
设置波特率
- /**
- *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*/
- }
先写这么多,剩余的明日持续。下一篇笔记中将给出怎么使用串口的收发中止和环形缓冲区来完成较为完善的串口驱动。