打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
基于STM32的ch438串口扩展芯片使用

CH438串口扩展芯片是一个一对八的串口扩展芯片,在一些串口需要过多的场合比较有用。这个串口芯片事实上并没有占用MCU的串口它实际上是使用了8个IO口做数据的传输。下面我就简单介绍一下怎么使用STM32驱动这个串口扩展芯片。并演示一个用CH438发送一段MODBUS码给电脑,电脑发给STM32的数据数据也回显示到电脑上.

CH438我用的是44管脚的LQFP44封装。

实际的电路是这样的:

 

需要注意的几点就是:RXT代表的是复位应该接上拉电阻到电源,我用的是STM32的复位电路共用。这里不能悬空。

晶振使用的是22.1184MHz晶振频率很高注意起振电容的选择。我采用的是20pf。

D0~D7与STM32 的PC0~7连接,这八位是数据传输位,其他的几位都是控制位。本次接收数据使用到了本芯片和STM32的中断,INT叫对应的就是中断线。注意这个管脚不能连接到PC口上因为PC口已经当做数据口用了,如果连接到PC口高八位上,在芯片读写数据的时候出异常。

下面这些是芯片内部的寄存器:主要就是配置他们。

  1. #ifndef _CH438_H
  2. #define _CH438_H
  3. #include "sys.h"
  4. #include "delay.h"
  5. #define REG_RBR_ADDR 0x00 /* 串口0接收缓冲寄存器地址 */
  6. #define REG_THR_ADDR 0x00 /* 串口0发送保持寄存器地址 */
  7. #define REG_IER_ADDR 0x01 /* 串口0中断使能寄存器地址 */
  8. #define REG_IIR_ADDR 0x02 /* 串口0中断识别寄存器地址 */
  9. #define REG_FCR_ADDR 0x02 /* 串口0FIFO控制寄存器地址 */
  10. #define REG_LCR_ADDR 0x03 /* 串口0线路控制寄存器地址 */
  11. #define REG_MCR_ADDR 0x04 /* 串口0MODEM控制寄存器地址 */
  12. #define REG_LSR_ADDR 0x05 /* 串口0线路状态寄存器地址 */
  13. #define REG_MSR_ADDR 0x06 /* 串口0MODEM状态寄存器地址 */
  14. #define REG_SCR_ADDR 0x07 /* 串口0用户可定义寄存器地址 */
  15. #define REG_DLL_ADDR 0x00 /* 波特率除数锁存器低8位字节地址 */
  16. #define REG_DLM_ADDR 0x01 /* 波特率除数锁存器高8位字节地址 */
  17. /* CH438内部串口0~7 专用状态寄存器 */
  18. #define REG_SSR_ADDR 0x4F /* 专用状态寄存器地址 */
  19. /* IER寄存器的位 */
  20. #define BIT_IER_RESET 0x80 /* 该位置1则软复位该串口 */
  21. #define BIT_IER_LOWPOWER 0x40 /* 该位为1则关闭该串口的内部基准时钟 */
  22. #define BIT_IER_SLP 0x20 /* 串口0是SLP,为1则关闭时钟震荡器 */
  23. #define BIT_IER1_CK2X 0x20 /* 串口1是CK2X,为1则强制将外部时钟信号2倍频后作为内部基准时钟 */
  24. #define BIT_IER_IEMODEM 0x08 /* 该位为1允许MODEM输入状态变化中断 */
  25. #define BIT_IER_IELINES 0x04 /* 该位为1允许接收线路状态中断 */
  26. #define BIT_IER_IETHRE 0x02 /* 该位为1允许发送保持寄存器空中断 */
  27. #define BIT_IER_IERECV 0x01 /* 该位为1允许接收到数据中断 */
  28. /* IIR寄存器的位 */
  29. #define BIT_IIR_FIFOENS1 0x80
  30. #define BIT_IIR_FIFOENS0 0x40 /* 该2位为1表示起用FIFO */
  31. /* 中断类型:0001没有中断,0110接收线路状态中断,0100接收数据可用中断,1100接收数据超时中断,0010THR寄存器空中断,0000MODEM输入变化中断 */
  32. #define BIT_IIR_IID3 0x08
  33. #define BIT_IIR_IID2 0x04 //接受数据可用
  34. #define BIT_IIR_IID1 0x02 //THR寄存器空中断
  35. #define BIT_IIR_NOINT 0x01
  36. /* FCR寄存器的位 */
  37. /* 触发点: 00对应1个字节,01对应16个字节,10对应64个字节,11对应112个字节 */
  38. #define BIT_FCR_RECVTG1 0x80 /* 设置FIFO的中断和自动硬件流控制的触发点 */
  39. #define BIT_FCR_RECVTG0 0x40 /* 设置FIFO的中断和自动硬件流控制的触发点 */
  40. #define BIT_FCR_TFIFORST 0x04 /* 该位置1则清空发送FIFO中的数据 */
  41. #define BIT_FCR_RFIFORST 0x02 /* 该位置1则清空接收FIFO中的数据 */
  42. #define BIT_FCR_FIFOEN 0x01 /* 该位置1则起用FIFO,为0则禁用FIFO */
  43. /* LCR寄存器的位 */
  44. #define BIT_LCR_DLAB 0x80 /* 为1才能存取DLL,DLM,为0才能存取RBR/THR/IER */
  45. #define BIT_LCR_BREAKEN 0x40 /* 为1则强制产生BREAK线路间隔*/
  46. /* 设置校验格式:当PAREN为1时,00奇校验,01偶校验,10标志位(MARK,置1),11空白位(SPACE,清0) */
  47. #define BIT_LCR_PARMODE1 0x20 /* 设置奇偶校验位格式 */
  48. #define BIT_LCR_PARMODE0 0x10 /* 设置奇偶校验位格式 */
  49. #define BIT_LCR_PAREN 0x08 /* 为1则允许发送时产生和接收校验奇偶校验位 */
  50. #define BIT_LCR_STOPBIT 0x04 /* 为1则两个停止位,为0一个停止位 */
  51. /* 设置字长度:00则5个数据位,01则6个数据位,10则7个数据位,11则8个数据位 */
  52. #define BIT_LCR_WORDSZ1 0x02 /* 设置字长长度 */
  53. #define BIT_LCR_WORDSZ0 0x01
  54. /* MCR寄存器的位 */
  55. #define BIT_MCR_AFE 0x20 /* 为1允许CTS和RTS硬件自动流控制 */
  56. #define BIT_MCR_LOOP 0x10 /* 为1使能内部回路的测试模式 */
  57. #define BIT_MCR_OUT2 0x08 /* 为1允许该串口的中断请求输出 */
  58. #define BIT_MCR_OUT1 0x04 /* 为用户定义的MODEM控制位 */
  59. #define BIT_MCR_RTS 0x02 /* 该位为1则RTS引脚输出有效 */
  60. #define BIT_MCR_DTR 0x01 /* 该位为1则DTR引脚输出有效 */
  61. /* LSR寄存器的位 */
  62. #define BIT_LSR_RFIFOERR 0x80 /* 为1表示在接收FIFO中存在至少一个错误 */
  63. #define BIT_LSR_TEMT 0x40 /* 为1表示THR和TSR全空 */
  64. #define BIT_LSR_THRE 0x20 /* 为1表示THR空*/
  65. #define BIT_LSR_BREAKINT 0x10 /* 该位为1表示检测到BREAK线路间隔 */
  66. #define BIT_LSR_FRAMEERR 0x08 /* 该位为1表示读取数据帧错误 */
  67. #define BIT_LSR_PARERR 0x04 /* 该位为1表示奇偶校验错误 */
  68. #define BIT_LSR_OVERR 0x02 /* 为1表示接收FIFO缓冲区溢出 */
  69. #define BIT_LSR_DATARDY 0x01 /* 该位为1表示接收FIFO中有接收到的数据 */
  70. /* MSR寄存器的位 */
  71. #define BIT_MSR_DCD 0x80 /* 该位为1表示DCD引脚有效 */
  72. #define BIT_MSR_RI 0x40 /* 该位为1表示RI引脚有效 */
  73. #define BIT_MSR_DSR 0x20 /* 该位为1表示DSR引脚有效 */
  74. #define BIT_MSR_CTS 0x10 /* 该位为1表示CTS引脚有效 */
  75. #define BIT_MSR_DDCD 0x08 /* 该位为1表示DCD引脚输入状态发生变化过 */
  76. #define BIT_MSR_TERI 0x04 /* 该位为1表示RI引脚输入状态发生变化过 */
  77. #define BIT_MSR_DDSR 0x02 /* 该位为1表示DSR引脚输入状态发生变化过 */
  78. #define BIT_MSR_DCTS 0x01 /* 该位为1表示CTS引脚输入状态发生变化过 */
  79. /* 中断状态码 */
  80. #define INT_NOINT 0x01 /* 没有中断 */
  81. #define INT_THR_EMPTY 0x02 /* THR空中断 */
  82. #define INT_RCV_OVERTIME 0x0C /* 接收超时中断 */
  83. #define INT_RCV_SUCCESS 0x04 /* 接收数据可用中断 */
  84. #define INT_RCV_LINES 0x06 /* 接收线路状态中断 */
  85. #define INT_MODEM_CHANGE 0x00 /* MODEM输入变化中断 */
  86. #define CH438_IIR_FIFOS_ENABLED 0xC0 /* 起用FIFO */
  87. #define WR PDout(3)
  88. #define ALE PDout(7)
  89. #define RD PDout(4)
  90. #define CS PDout(5)
  91. #define AMOD PDout(6)
  92. #define INT PDout(1)
  93. void SetOutPut(void);
  94. void SetInPut(void);
  95. void CH438_Init(void);
  96. void CH438WriteReg(u8 add,u8 data);
  97. u8 CH438ReadReg(u8 add);
  98. unsigned char CH438_CheckIIR(unsigned char num);
  99. void CH438_CloseSeril(unsigned char num);
  100. void CH438_CloseALLSeril(void);
  101. void CH438_ResetSeril(unsigned char num);
  102. void CH438_SetBandrate(unsigned char num, unsigned long value);
  103. void CH438_UARTInit(unsigned char num);
  104. void CH438_SendDatas(unsigned char num, unsigned char* sendbuff,unsigned char len);
  105. unsigned char CH438_RecvDatas(unsigned char num, unsigned char* revbuff);
  106. void CH438_TranConfig(unsigned char num);
  107. void CH438_INTConfig(unsigned char num);
  108. void CH438_AutoHFCtrl(unsigned char num);
  109. void CH438_RegTEST(unsigned char num);
  110. void CH438_Uart_Init(unsigned char num,unsigned long value);
  111. #endif

上面就是CH438.h头文件,以下就是main函数,本程序只打开了串口2

  1. int main()
  2. {
  3. u8 ssr =0 ;
  4. u8 AddCom[8] = {01,05,01,17,255,00,221,195}; //增压
  5. delay_init();
  6. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  7. uart_init(9600);
  8. LCD_Init();
  9. CH438_Init();
  10. CH438_ResetSeril(2); //软件复位串口2
  11. CH438_Uart_Init(2,9600); //串口2打开 波特率9600
  12. delay_ms(100);
  13. while(1)
  14. {
  15. CH438_SendDatas(2,AddCom,8);
  16. CH438_SendDatas(2,(u8*)"\r\n",2);
  17. delay_ms(1000);
  18. }
  19. }

下面是主要的函数

  1. #include "ch438.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "lcd.h"
  5. #define Fpclk 1843200 /* 定义内部时钟频率,默认外部晶振的12分频 */
  6. #define MaxRecvLen 50 /* 接收缓冲区大小 */
  7. const unsigned char offsetadd[] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,}; /* 串口号的偏移地址 */
  8. const unsigned char Interruptnum[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,}; /* SSR寄存器中断号对应值 */
  9. unsigned char Revbuff[MaxRecvLen]; /* 接收缓存区 */
  10. unsigned char RevLen; /* 接收计数 */
  11. void SetOutPut() //IO输出模式
  12. {
  13. GPIOC->CRL &=0;
  14. GPIOC->CRL = 0X33333333;
  15. }
  16. void SetInPut()//IO输入模式
  17. {
  18. GPIOC->CRL &=0;
  19. GPIOC->CRL = 0X88888888;
  20. }
  21. void CH438_Init() //IO口中断等初始化
  22. {
  23. GPIO_InitTypeDef GPIO_InitStructure;
  24. NVIC_InitTypeDef NVIC_InitStructure;
  25. EXTI_InitTypeDef EXTI_InitStructure;
  26. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
  27. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  28. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  29. GPIO_InitStructure.GPIO_Pin = 0X00FF;
  30. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  31. GPIO_Init(GPIOC,&GPIO_InitStructure);
  32. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  33. GPIO_Init(GPIOD,&GPIO_InitStructure);
  34. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  35. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  36. GPIO_Init(GPIOD,&GPIO_InitStructure);
  37. GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource1);
  38. EXTI_InitStructure.EXTI_Line = EXTI_Line1;
  39. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  40. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  41. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  42. EXTI_Init(&EXTI_InitStructure);
  43. NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  44. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  45. NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
  46. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  47. NVIC_Init(&NVIC_InitStructure);
  48. EXTI_ClearITPendingBit(EXTI_Line1);
  49. AMOD = 1;
  50. }
  51. void CH438WriteReg(u8 add,u8 data) //写一个字节到寄存器
  52. {
  53. u16 value ;
  54. CS = 1;
  55. WR = 1;
  56. RD = 1;
  57. SetOutPut();
  58. GPIOC->ODR = (GPIOC->ODR&0XFF00)|add; //低八位十数据位确保高八位数据不变 写寄存器地址
  59. CS = 0;
  60. ALE =1;
  61. delay_us(1);
  62. ALE = 0;
  63. GPIOC->ODR = (GPIOC->ODR&0XFF00)|data; //写数据
  64. WR =0 ;
  65. delay_us(1);
  66. WR =1;
  67. CS =1;
  68. }
  69. u8 CH438ReadReg(u8 add) //读取一个字节
  70. {
  71. u8 value;
  72. u8 value1;
  73. CS = 1;
  74. WR =1;
  75. RD =1;
  76. SetOutPut(); //
  77. CS = 0;
  78. ALE =1;
  79. GPIOC->ODR = (GPIOC->ODR&0XFF00)|add;
  80. ALE = 0;
  81. SetInPut();
  82. RD = 0;
  83. value = GPIO_ReadInputData(GPIOC);
  84. RD =1;
  85. CS =1;
  86. return value;
  87. }
  88. unsigned char CH438_CheckIIR(unsigned char num)
  89. {
  90. unsigned char value;
  91. value = CH438ReadReg( offsetadd[num] | REG_IIR_ADDR );
  92. return value;
  93. }
  94. void CH438_CloseSeril(unsigned char num) //关闭某位串口
  95. {
  96. CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_LOWPOWER);
  97. }
  98. void CH438_CloseALLSeril(void) //关闭所有串口
  99. {
  100. CH438WriteReg(offsetadd[0]|REG_IER_ADDR, BIT_IER_LOWPOWER|BIT_IER_SLP);
  101. }
  102. void CH438_ResetSeril(unsigned char num) //复位串口
  103. {
  104. CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_RESET);
  105. }
  106. void CH438_SetBandrate(unsigned char num, unsigned long value)//设置波特率 未使用此函数
  107. {
  108. uint8_t dlab=0;
  109. uint16_t bandspeed;
  110. bandspeed = Fpclk/16/value;
  111. CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, BIT_LCR_DLAB );
  112. CH438WriteReg(offsetadd[num]|REG_DLL_ADDR, (uint8_t)bandspeed);
  113. CH438WriteReg(offsetadd[num]|REG_DLM_ADDR, (uint8_t)(bandspeed>>8));
  114. printf("bandrate: %d\n", bandspeed);
  115. printf("DLM: %d\n", CH438ReadReg(offsetadd[num]|REG_DLM_ADDR));
  116. printf("DLL: %d\n", CH438ReadReg(offsetadd[num]|REG_DLL_ADDR));
  117. }
  118. void CH438_UARTInit(unsigned char num)//初始化 未使用到
  119. {
  120. CH438_SetBandrate(num, 9600); /* CH438串口1波特率设置 */
  121. CH438_TranConfig(num); /* CH438串口1数据格式配置及FIFO大小 */
  122. }
  123. //发送数据
  124. void CH438_SendDatas(unsigned char num, unsigned char* sendbuff,unsigned char len)
  125. {
  126. do
  127. {
  128. while((CH438ReadReg(offsetadd[num]|REG_LSR_ADDR)&BIT_LSR_THRE)==0); //LSR->THRE==1 保持寄存器空
  129. CH438WriteReg(offsetadd[num]|REG_THR_ADDR,*sendbuff++);
  130. }while(--len);
  131. }
  132. //接收数据
  133. unsigned char CH438_RecvDatas(unsigned char num, unsigned char* revbuff)
  134. {
  135. uint8_t len=0;
  136. uint8_t *p_rev;
  137. p_rev = revbuff;
  138. while( ( CH438ReadReg( offsetadd[num]|REG_LSR_ADDR ) & BIT_LSR_DATARDY ) == 0 ); /*等待数据准备好 */
  139. while((CH438ReadReg(offsetadd[num]|REG_LSR_ADDR)&BIT_LSR_DATARDY)) //LSR->DATARDY==1
  140. {
  141. *p_rev = CH438ReadReg(offsetadd[num]|REG_RBR_ADDR);
  142. p_rev++;
  143. len++;
  144. }
  145. return len;
  146. }
  147. void CH438_TranConfig(unsigned char num)
  148. {
  149. /* 发送数据格式:8位数据,无校验,1个停止位 */
  150. CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0);
  151. /* 设置FIFO模式,触发点为112字节 */
  152. CH438WriteReg(offsetadd[num]|REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN);
  153. CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,CH438ReadReg(offsetadd[num]|REG_FCR_ADDR)| BIT_FCR_TFIFORST|BIT_FCR_RFIFORST);
  154. }
  155. void CH438_INTConfig(unsigned char num)
  156. {
  157. /* 注意: CH438打开BIT_IER_IETHRE中断(0->1),会产生一个发生空中断 */
  158. CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV );
  159. CH438_CheckIIR(num);
  160. CH438WriteReg(offsetadd[num]|REG_MCR_ADDR, BIT_MCR_OUT2 | BIT_MCR_RTS | BIT_MCR_DTR);//可以产生一个实际的中断
  161. }
  162. void CH438_AutoHFCtrl(unsigned char num)
  163. {
  164. CH438WriteReg( offsetadd[num]|REG_MCR_ADDR, BIT_MCR_AFE | BIT_MCR_OUT2 | BIT_MCR_RTS );/* 设置MCR寄存器的AFE和RTS为1 */
  165. }
  166. //中断处理函数
  167. void EXTI1_IRQHandler()
  168. {
  169. u8 gInterruptStatus;
  170. u8 InterruptStatus;
  171. u8 i;
  172. static u8 j ;
  173. if(EXTI_GetITStatus(EXTI_Line1)!= RESET)
  174. {
  175. gInterruptStatus = CH438ReadReg( REG_SSR_ADDR );
  176. if(!gInterruptStatus)
  177. {
  178. EXTI_ClearITPendingBit(EXTI_Line1);
  179. return ;
  180. }
  181. for(i=0; i<8; i++)
  182. {
  183. if( gInterruptStatus & Interruptnum[i] ) /* 检测哪个串口发生中断 */
  184. {
  185. InterruptStatus = CH438ReadReg( offsetadd[i] | REG_IIR_ADDR ) & 0x0f; /* 读串口的中断状态 */
  186. switch( InterruptStatus )
  187. {
  188. case INT_NOINT: /* 没有中断 */
  189. break;
  190. case INT_THR_EMPTY: /* THR空中断 */
  191. break;
  192. case INT_RCV_OVERTIME: /* 接收超时中断 */
  193. RevLen = CH438_RecvDatas(i, Revbuff);
  194. CH438_SendDatas(i, Revbuff, RevLen);
  195. break;
  196. case INT_RCV_SUCCESS: /* 接收数据可用中断 */
  197. RevLen = CH438_RecvDatas(i, Revbuff);
  198. CH438_SendDatas(i, Revbuff, RevLen);
  199. break;
  200. case INT_RCV_LINES: /* 接收线路状态中断 */
  201. CH438ReadReg( offsetadd[i] | REG_LSR_ADDR );
  202. break;
  203. case INT_MODEM_CHANGE: /* MODEM输入变化中断 */
  204. CH438ReadReg( offsetadd[i] | REG_MSR_ADDR );
  205. break;
  206. default:
  207. break;
  208. }
  209. }
  210. }
  211. EXTI_ClearITPendingBit(EXTI_Line1);
  212. }
  213. }
  214. void CH438_RegTEST(unsigned char num)//测试使用的函数
  215. {
  216. printf("current test serilnum: %d \r\n",(unsigned short)offsetadd[num]);
  217. printf("IER: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_IER_ADDR));//?IER
  218. printf("IIR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_IIR_ADDR));//?IIR
  219. printf("LCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_LCR_ADDR));//?LCR
  220. printf("MCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_MCR_ADDR));//?MCR
  221. printf("LSR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_LSR_ADDR));//?LSR
  222. printf("MSR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_MSR_ADDR));//?MSR
  223. //CH438WriteReg(offsetadd[num] | REG_SCR_ADDR, 0x78);
  224. printf("SCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_SCR_ADDR));//?SCR
  225. printf("FCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_FCR_ADDR));//?SCR
  226. }
  227. //串口初始化函数 输入参数 串口号和波特率
  228. void CH438_Uart_Init(unsigned char num,unsigned long value)
  229. {
  230. uint8_t dlab=0;
  231. uint16_t bandspeed;
  232. dlab = CH438ReadReg(offsetadd[num]|REG_IER_ADDR);
  233. dlab &= 0xDF;
  234. CH438WriteReg(offsetadd[num]|REG_IER_ADDR, dlab);
  235. dlab = CH438ReadReg(offsetadd[num]|REG_LCR_ADDR);
  236. dlab |= 0x80; //置LCR寄存器DLAB位为1
  237. CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, dlab);
  238. bandspeed = Fpclk/16/value;
  239. CH438WriteReg(offsetadd[num]|REG_DLL_ADDR, (uint8_t)bandspeed);
  240. CH438WriteReg(offsetadd[num]|REG_DLM_ADDR, (uint8_t)(bandspeed>>8));
  241. dlab &= 0x7F; //置IIR寄存器DLAB位为0
  242. CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, dlab);
  243. CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN );
  244. CH438WriteReg(offsetadd[num]|REG_LCR_ADDR,BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0 );
  245. CH438WriteReg(offsetadd[num]|REG_IER_ADDR,BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV);
  246. CH438WriteReg(offsetadd[num]|REG_MCR_ADDR,BIT_MCR_OUT2 | BIT_MCR_RTS | BIT_MCR_DTR);
  247. CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,CH438ReadReg(offsetadd[num]|REG_FCR_ADDR)| BIT_FCR_TFIFORST|BIT_FCR_RFIFORST);
  248. }

 

实验结果如下:

 

垃圾CSDN

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
. GPIO原理与配置(跑马灯,蜂鸣器,按键)
超详细陀螺仪MPU6050模块输出姿态角(有完整版源码)
STM32 LwIP测试过程简介
stm32 AD模数转换[操作寄存器+库函数]-Changing's Blog
STM32和NRF24L01实现无线传输
NRF24L01 MSP430发送接收程序
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服