新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Freescale 9S12 系列單片機(jī)應(yīng)用筆記(SCI)1

Freescale 9S12 系列單片機(jī)應(yīng)用筆記(SCI)1

作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏

SCI模塊應(yīng)用筆記(1)

UART,也就是異步串行通訊接口是單片機(jī)中最常見的外設(shè),幾乎每種類型的單片機(jī)都必備1到2個(gè)UART接口,9S12系列單片機(jī)也不例外。不過,摩托羅拉給他自己的單片機(jī)的串口起了個(gè)很有個(gè)性的縮寫名稱SCI(serialcommunicationinterface),其實(shí)就是我們常說的UART。

本文引用地址:http://m.butianyuan.cn/article/201611/318823.htm

各種單片機(jī)串口的編程都大同小異,無非就是設(shè)置波特率、起始位、停止位、校驗(yàn)位等等。下面通過給出編程例子的方式分別介紹。

設(shè)置波特率

  1. /**
  2. *SettheBaudRateoftheSCI.
  3. *@paramport,portcanbeSCI0/SCI1
  4. *@parambaudRate,thewantedbaudrate.
  5. *@parambusClk,TheSCImoduleclock.
  6. */
  7. voidSCISetBaudRate(unsignedcharport,unsignedlongbaudRate,unsignedlongbusClk)
  8. {
  9. unsignedshortbaudRateReg;
  10. baudRateReg=(unsignedshort)(busClk/baudRate/16);
  11. if(port==SCI0)
  12. {
  13. //HerewemustwriteBDHfirst!
  14. SCI0BDH=(0x1f&(baudRateReg>>8));
  15. SCI0BDL=(0xff&baudRateReg);
  16. }
  17. elseif(port==SCI1)
  18. {
  19. SCI1BDH=(0x1f&(baudRateReg>>8));
  20. SCI1BDL=(0xff&baudRateReg);
  21. }
  22. else
  23. {
  24. //Somethingmustgowrong.Donothinghere!
  25. }
  26. }

設(shè)置奇偶校驗(yàn)位

  1. /**
  2. *Enable/DisableparityfunctionandsettheParitytype
  3. *@paramportportcanbeSCI0/SCI1
  4. *@paramisEnable0fordisableparityfunction,1forenable
  5. *@paramtype0forEvenParity,1forOddParity
  6. */
  7. voidSCISetParity(unsignedcharport,unsignedcharisEnable,unsignedchartype)
  8. {
  9. if(port==SCI0)
  10. {
  11. SCI0CR1_PE=(isEnable&0x01);
  12. SCI0CR1_PT=(type&0x01);
  13. }
  14. elseif(port==SCI1)
  15. {
  16. SCI1CR1_PE=(isEnable&0x01);
  17. SCI1CR1_PT=(type&0x01);
  18. }
  19. else
  20. {
  21. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  22. }
  23. }


使能數(shù)據(jù)位的長度

  1. /**
  2. *SettheDataFormatModeBit
  3. *@paramportportcanbeSCI0/SCI1
  4. *@parambitsmustbe8or9
  5. */
  6. voidSCISetDataBit(unsignedcharport,unsignedcharbits)
  7. {
  8. if(port==SCI0)
  9. {
  10. switch(bits)
  11. {
  12. case8:
  13. SCI0CR1_M=0;/*1startbit,8databits,1stopbit*/
  14. break;
  15. case9:
  16. SCI0CR1_M=1;/*1startbit,9databits,1stopbit*/
  17. break;
  18. default:
  19. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  20. break;
  21. }
  22. }
  23. elseif(port==SCI1)
  24. {
  25. switch(bits)
  26. {
  27. case8:
  28. SCI1CR1_M=0;/*1startbit,8databits,1stopbit*/
  29. break;
  30. case9:
  31. SCI1CR1_M=1;/*1startbit,9databits,1stopbit*/
  32. break;
  33. default:
  34. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  35. break;
  36. }
  37. }
  38. else
  39. {
  40. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  41. }
  42. }


設(shè)置串口的工作模式

NORMAL_MODE是我們通常用的模式

LOOP_MODE是自發(fā)自收模式

SING_WIRE_MODE就是收發(fā)公用一條數(shù)據(jù)線的模式

  1. /**
  2. *Settheworkmodeofoperation
  3. *@paramportportcanbeSCI0/SCI1
  4. *@parammodemodecanbeNORMAL_MODE/LOOP_MODE/SING_WIRE_MODE
  5. */
  6. voidSCISetWorkMode(unsignedcharport,unsignedcharmode)
  7. {
  8. if(port==SCI0)
  9. {
  10. switch(mode)
  11. {
  12. caseNORMAL_MODE:
  13. SCI0CR1_LOOPS=0;
  14. SCI0CR1_RSRC=0;
  15. break;
  16. caseLOOP_MODE:
  17. SCI0CR1_LOOPS=1;
  18. SCI0CR1_RSRC=0;
  19. break;
  20. caseSING_WIRE_MODE:
  21. SCI0CR1_LOOPS=1;
  22. SCI0CR1_RSRC=1;
  23. break;
  24. default:
  25. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  26. break;
  27. }
  28. }
  29. elseif(port==SCI1)
  30. {
  31. switch(mode)
  32. {
  33. caseNORMAL_MODE:
  34. SCI1CR1_LOOPS=0;
  35. SCI1CR1_RSRC=0;
  36. break;
  37. caseLOOP_MODE:
  38. SCI1CR1_LOOPS=1;
  39. SCI1CR1_RSRC=0;
  40. break;
  41. caseSING_WIRE_MODE:
  42. SCI1CR1_LOOPS=1;
  43. SCI1CR1_RSRC=1;
  44. break;
  45. default:
  46. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  47. break;
  48. }
  49. }
  50. else
  51. {
  52. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  53. }
  54. }

設(shè)置SCI模塊是否在Wait模式下工作

  1. /**
  2. *Enable/DisabletheSCIinwaitmode
  3. *@paramportportcanbeSCI0/SCI1
  4. *@parammodemodecanbeRUN_MODE/WAIT_MODE
  5. */
  6. voidSCISetPowerMode(unsignedcharport,unsignedcharmode)
  7. {
  8. if(port==SCI0)
  9. {
  10. switch(mode)
  11. {
  12. caseRUN_MODE:
  13. SCI0CR1_SCISWAI=0;
  14. break;
  15. caseWAIT_MODE:
  16. SCI0CR1_SCISWAI=1;
  17. break;
  18. default:
  19. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  20. break;
  21. }
  22. }
  23. elseif(port==SCI1)
  24. {
  25. switch(mode)
  26. {
  27. caseRUN_MODE:
  28. SCI1CR1_SCISWAI=0;
  29. break;
  30. caseWAIT_MODE:
  31. SCI1CR1_SCISWAI=1;
  32. break;
  33. default:
  34. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  35. break;
  36. }
  37. }
  38. else
  39. {
  40. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  41. }
  42. }

使能SCI模塊的接收功能

  1. /**
  2. *Enable/DisableSCIReceiver
  3. *@paramportportcanbeSCI0/SCI1
  4. *@paramisEnable0disable1enable
  5. */
  6. voidSCIEnableRecv(unsignedcharport,unsignedcharisEnable)
  7. {
  8. if(port==SCI0)
  9. {
  10. SCI0CR2_RE=(isEnable&0x01);
  11. }
  12. elseif(port==SCI1)
  13. {
  14. SCI1CR2_RE=(isEnable&0x01);
  15. }
  16. else
  17. {
  18. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  19. }
  20. }

使能SCI模塊的發(fā)送功能

  1. /**
  2. *Enable/DisableSCITransmitter
  3. *@paramportportcanbeSCI0/SCI1
  4. *@paramisEnable0disable1enable
  5. */
  6. voidSCIEnableTrans(unsignedcharport,unsignedcharisEnable)
  7. {
  8. if(port==SCI0)
  9. {
  10. SCI0CR2_TE=(isEnable&0x01);
  11. }
  12. elseif(port==SCI1)
  13. {
  14. SCI1CR2_TE=(isEnable&0x01);
  15. }
  16. else
  17. {
  18. //Ifcoderunhere,somethingmustgowrong.Donothinghere!
  19. }
  20. }

發(fā)送數(shù)據(jù)

  1. /**
  2. *SendacharthrounghSCImodule.
  3. *@paramportportcanbeSCI0/SCI1
  4. *@paramsthedatatobesent
  5. */
  6. voidSCIPutChar(unsignedcharport,unsignedchars)
  7. {
  8. if(port==SCI0)
  9. {
  10. while(SCI0SR1_TDRE==0);//SCI0SR1_TC是發(fā)送完成
  11. SCI0DRL=s;
  12. }
  13. else
  14. {
  15. while(SCI1SR1_TDRE==0);//SCI1SR1_TC
  16. SCI1DRL=s;
  17. }
  18. }
  19. /**
  20. *SendacharstringthrounghSCImodule.
  21. *@paramportportcanbeSCI0/SCI1
  22. *@param*strthestringtobesent
  23. */
  24. voidSCIPutStr(unsignedcharport,unsignedchar*str)
  25. {
  26. while(0!=*str)
  27. {
  28. SCIPutChar(port,*str);
  29. str++;
  30. }
  31. }
  32. /**
  33. *SenddatathrounghSCImodule.
  34. *@paramportportcanbeSCI0/SCI1
  35. *@param*ppointertothedatatobesent
  36. *@paramsizethesize(byte)ofthedata
  37. */
  38. voidSCIWrite(unsignedcharport,void*p,intsize)
  39. {
  40. unsignedchar*str=(unsignedchar*)p;
  41. while(size>0)
  42. {
  43. SCIPutChar(port,*str);
  44. str++;
  45. size--;
  46. }
  47. }
  48. /**
  49. *Sendashortintvalue(BigEndian)throunghSCImodule.
  50. *@paramportportcanbeSCI0/SCI1
  51. *@paramithedatatobesent
  52. */
  53. voidSCIPutShortBigEndian(unsignedcharport,shorti)
  54. {
  55. char*p=(char*)&i;
  56. SCIPutChar(port,p[0]);
  57. SCIPutChar(port,p[1]);
  58. }
  59. /**
  60. *Sendashortintvalue(LittleEndian)throunghSCImodule.
  61. *@paramportportcanbeSCI0/SCI1
  62. *@paramithedatatobesent
  63. */
  64. voidSCIPutShortLittleEndian(unsignedcharport,shorti)
  65. {
  66. char*p=(char*)&i;
  67. SCIPutChar(port,p[1]);
  68. SCIPutChar(port,p[0]);
  69. }
  70. /**
  71. *Sendalongintvalue(BigEndian)throunghSCImodule.
  72. *@paramportportcanbeSCI0/SCI1
  73. *@paramithedatatobesent
  74. */
  75. voidSCIPutLongBigEndian(unsignedcharport,longi)
  76. {
  77. char*p=(char*)&i;
  78. SCIPutChar(port,p[0]);
  79. SCIPutChar(port,p[1]);
  80. SCIPutChar(port,p[2]);
  81. SCIPutChar(port,p[3]);
  82. }
  83. /**
  84. *Sendalongintvalue(LittleEndian)throunghSCImodule.
  85. *@paramportportcanbeSCI0/SCI1
  86. *@paramithedatatobesent
  87. */
  88. voidSCIPutLongLittleEndian(unsignedcharport,longi)
  89. {
  90. char*p=(char*)&i;
  91. SCIPutChar(port,p[3]);
  92. SCIPutChar(port,p[2]);
  93. SCIPutChar(port,p[1]);
  94. SCIPutChar(port,p[0]);
  95. }


接收數(shù)據(jù)

  1. /**
  2. *ReceiveachardatafromSCImodule,noreply.
  3. *@paramportportcanbeSCI0/SCI1
  4. *@returnthereceivedchar
  5. */
  6. unsignedcharSCIGetChar(unsignedcharport)
  7. {
  8. if(port==SCI0)
  9. {
  10. while(SCI0SR1_RDRF==0);
  11. returnSCI0DRL;
  12. }
  13. else
  14. {
  15. while(SCI1SR1_RDRF==0);
  16. returnSCI1DRL;
  17. }
  18. }

相應(yīng)的頭文件

  1. /**
  2. *filesci.h
  3. *authorLiYuan
  4. *platform:mc9s12dp256B
  5. *date:2012-4-16
  6. *version:1.0.0
  7. *description:SCI(SerialCommunicationInterface)SupportCode
  8. */
  9. #ifndef_SCI_H_
  10. #define_SCI_H_
  11. #defineSCI00
  12. #defineSCI11
  13. #defineIDLE_LINE0
  14. #defineADDRESS_MARK1
  15. #defineNORMAL_MODE0
  16. #defineLOOP_MODE1
  17. #defineSING_WIRE_MODE2
  18. #defineRUN_MODE0
  19. #defineWAIT_MODE1
  20. /*FunctionDeclaration*/
  21. /**
  22. *SettheBaudRateoftheSCI.
  23. *@paramport,portcanbeSCI0/SCI1
  24. *@parambaudRate,thewantedbaudrate.
  25. *@parambusClk,TheSCImoduleclock.
  26. */
  27. voidSCISetBaudRate(unsignedcharport,unsignedlongbaudRate,unsignedlongbusClk);
  28. /**
  29. *SettheInterruptEnableBit
  30. *@paramportportcanbeSCI0/SCI1
  31. *@paramtieTransmitterInterruptEnableBIt
  32. *@paramtcieTransmissionCompleteInterruptEnableBIt
  33. *@paramrieReceiverFullInterruptEnableBIt
  34. *@paramilieIdleLineInterruptEnableBIt
  35. *0InterruptrequestsDisabled
  36. *1InterruptrequestsEnabled
  37. */
  38. voidSCISetIEBit(unsignedcharport,unsignedchartie,unsignedchartcie,unsignedcharrie,unsignedcharilie);
  39. /**
  40. *EnableTheTxinterrupt(TransmitterInterruptEnableBIt)
  41. *@paramport,portcanbeSCI0/SCI1
  42. */
  43. voidSCIEnableTxInt(unsignedcharport);
  44. /**
  45. *DisableTheTxinterrupt(TransmitterInterruptEnableBIt)
  46. *@paramport,portcanbeSCI0/SCI1
  47. */
  48. voidSCIDisTxInt(unsignedcharport);
  49. /**
  50. *Enable/DisableSCIReceiver
  51. *@paramportportcanbeSCI0/SCI1
  52. *@paramisEnable0disable1enable
  53. */
  54. voidSCIEnableRecv(unsignedcharport,unsignedcharisEnable);
  55. /**
  56. *Enable/DisableSCITransmitter
  57. *@paramportportcanbeSCI0/SCI1
  58. *@paramisEnable0disable1enable
  59. */
  60. voidSCIEnableTrans(unsignedcharport,unsignedcharisEnable);
  61. /**
  62. *SettheIdleLineType
  63. *@paramportportcanbeSCI0/SCI1
  64. *@paramtype0Idlecharbitcountbeginsafterstartbit
  65. *1Idlecharbitcountbeginsafterstopbit
  66. */
  67. voidSCISetIdleLineType(unsignedcharport,unsignedchartype);
  68. /**
  69. *SettheWakeupCondition.
  70. *@paramportportcanbeSCI0/SCI1
  71. *@paramcondi0forIdlelinewakeup,1foraddressmarkwakeup
  72. */
  73. voidSCISetWakeupCondi(unsignedcharport,unsignedcharcondi);
  74. /**
  75. *Enable/DisableparityfunctionandsettheParitytype
  76. *@paramportportcanbeSCI0/SCI1
  77. *@paramisEnable0fordisableparityfunction,1forenable
  78. *@paramtype0forEvenParity,1forOddParity
  79. */
  80. voidSCISetParity(unsignedcharport,unsignedcharisEnable,unsignedchartype);
  81. /**
  82. *SettheDataFormatModeBit
  83. *@paramportportcanbeSCI0/SCI1
  84. *@parambitsmustbe8or9
  85. */
  86. voidSCISetDataBit(unsignedcharport,unsignedcharbits);
  87. /**
  88. *Settheworkmodeofoperation
  89. *@paramportportcanbeSCI0/SCI1
  90. *@parammodemodecanbeNORMAL_MODE/LOOP_MODE/SING_WIRE_MODE
  91. */
  92. voidSCISetWorkMode(unsignedcharport,unsignedcharmode);
  93. /**
  94. *Enable/DisabletheSCIinwaitmode
  95. *@paramportportcanbeSCI0/SCI1
  96. *@parammodemodecanbeRUN_MODE/WAIT_MODE
  97. */
  98. voidSCISetPowerMode(unsignedcharport,unsignedcharmode);
  99. /**
  100. *SettheTXDIR(OnlyforSingleWireMODE)
  101. *@paramportportcanbeSCI0/SCI1
  102. *@paramdir0TXDusedasinput,1TXDusedasoutput
  103. */
  104. voidSCISetTXDIR(unsignedcharport,unsignedchardir);
  105. /**
  106. *SendacharthrounghSCImodule.
  107. *@paramportportcanbeSCI0/SCI1
  108. *@paramsthedatatobesent
  109. */
  110. voidSCIPutChar(unsignedcharport,unsignedchars);
  111. /**
  112. *ReceiveachardatafromSCImodule,noreply.
  113. *@paramportportcanbeSCI0/SCI1
  114. *@returnthereceivedchar
  115. */
  116. unsignedcharSCIGetChar(unsignedcharport);
  117. /**
  118. *Sendashortintvalue(BigEndian)throunghSCImodule.
  119. *@paramportportcanbeSCI0/SCI1
  120. *@paramithedatatobesent
  121. */
  122. voidSCIPutShortBigEndian(unsignedcharport,shorti);
  123. /**
  124. *Sendashortintvalue(LittleEndian)throunghSCImodule.
  125. *@paramportportcanbeSCI0/SCI1
  126. *@paramithedatatobesent
  127. */
  128. voidSCIPutShortLittleEndian(unsignedcharport,shorti);
  129. /**
  130. *Sendalongintvalue(BigEndian)throunghSCImodule.
  131. *@paramportportcanbeSCI0/SCI1
  132. *@paramithedatatobesent
  133. */
  134. voidSCIPutLongBigEndian(unsignedcharport,longi);
  135. /**
  136. *Sendalongintvalue(LittleEndian)throunghSCImodule.
  137. *@paramportportcanbeSCI0/SCI1
  138. *@paramithedatatobesent
  139. */
  140. voidSCIPutLongLittleEndian(unsignedcharport,longi);
  141. /**
  142. *SendacharstringthrounghSCImodule.
  143. *@paramportportcanbeSCI0/SCI1
  144. *@param*strthestringtobesent
  145. */
  146. voidSCIPutStr(unsignedcharport,unsignedchar*str);
  147. /**
  148. *SenddatathrounghSCImodule.
  149. *@paramportportcanbeSCI0/SCI1
  150. *@param*ppointertothedatatobesent
  151. *@paramsizethesize(byte)ofthedata
  152. */
  153. voidSCIWrite(unsignedcharport,void*p,intsize);
  154. #endif

下面給個(gè)簡單的例子

  1. #include/*commondefinesandmacros*/
  2. #include"derivative.h"/*derivative-specificdefinitions*/
  3. #include"sci.h"
  4. voidmain(void)
  5. {
  6. charC;
  7. EnableInterrupts;
  8. SCISetWorkMode(SCI0,NORMAL_MODE);
  9. SCISetPowerMode(SCI0,RUN_MODE);
  10. SCISetBaudRate(SCI0,9600,16384000L);//16MClock
  11. SCISetDataBit(SCI0,8);
  12. SCISetParity(SCI0,0,0);
  13. SCIEnableRecv(SCI0,1);
  14. SCIEnableTrans(SCI0,1);
  15. for(;;)
  16. {
  17. _FEED_COP();/*feedsthedog*/
  18. C=SCIGetChar(SCI0);
  19. SCIPutChar(SCI0,C);
  20. }/*loopforever*/
  21. /*pleasemakesurethatyouneverleavemain*/
  22. }


先寫這么多,剩下的明天繼續(xù)。下一篇筆記中將給出如何利用串口的收發(fā)中斷和環(huán)形緩沖區(qū)來實(shí)現(xiàn)較為完善的串口驅(qū)動(dòng)。



關(guān)鍵詞: Freescale9S12系列單片

評論


技術(shù)專區(qū)

關(guān)閉