- 下面是主要的函数
- #include "ch438.h"
- #include "delay.h"
- #include "usart.h"
- #include "lcd.h"
- #define Fpclk 1843200 /* 定义内部时钟频率,默认外部晶振的12分频 */
- #define MaxRecvLen 50 /* 接收缓冲区大小 */
- const unsigned char offsetadd[] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,}; /* 串口号的偏移地址 */
- const unsigned char Interruptnum[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,}; /* SSR寄存器中断号对应值 */
- unsigned char Revbuff[MaxRecvLen]; /* 接收缓存区 */
- unsigned char RevLen; /* 接收计数 */
- void SetOutPut() //IO输出模式
- {
- GPIOC->CRL &=0;
- GPIOC->CRL = 0X33333333;
- }
- void SetInPut()//IO输入模式
- {
- GPIOC->CRL &=0;
- GPIOC->CRL = 0X88888888;
- }
- void CH438_Init() //IO口中断等初始化
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- EXTI_InitTypeDef EXTI_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = 0X00FF;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC,&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
- GPIO_Init(GPIOD,&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- GPIO_Init(GPIOD,&GPIO_InitStructure);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource1);
- EXTI_InitStructure.EXTI_Line = EXTI_Line1;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- EXTI_ClearITPendingBit(EXTI_Line1);
- AMOD = 1;
- }
- void CH438WriteReg(u8 add,u8 data) //写一个字节到寄存器
- {
- u16 value ;
- CS = 1;
- WR = 1;
- RD = 1;
- SetOutPut();
- GPIOC->ODR = (GPIOC->ODR&0XFF00)|add; //低八位十数据位确保高八位数据不变 写寄存器地址
- CS = 0;
- ALE =1;
- delay_us(1);
- ALE = 0;
- GPIOC->ODR = (GPIOC->ODR&0XFF00)|data; //写数据
- WR =0 ;
- delay_us(1);
- WR =1;
- CS =1;
- }
- u8 CH438ReadReg(u8 add) //读取一个字节
- {
- u8 value;
- u8 value1;
- CS = 1;
- WR =1;
- RD =1;
- SetOutPut(); //
- CS = 0;
- ALE =1;
- GPIOC->ODR = (GPIOC->ODR&0XFF00)|add;
- ALE = 0;
- SetInPut();
- RD = 0;
- value = GPIO_ReadInputData(GPIOC);
- RD =1;
- CS =1;
- return value;
- }
- unsigned char CH438_CheckIIR(unsigned char num)
- {
- unsigned char value;
- value = CH438ReadReg( offsetadd[num] | REG_IIR_ADDR );
- return value;
- }
- void CH438_CloseSeril(unsigned char num) //关闭某位串口
- {
- CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_LOWPOWER);
- }
- void CH438_CloseALLSeril(void) //关闭所有串口
- {
- CH438WriteReg(offsetadd[0]|REG_IER_ADDR, BIT_IER_LOWPOWER|BIT_IER_SLP);
- }
- void CH438_ResetSeril(unsigned char num) //复位串口
- {
- CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_RESET);
- }
- void CH438_SetBandrate(unsigned char num, unsigned long value)//设置波特率 未使用此函数
- {
- uint8_t dlab=0;
- uint16_t bandspeed;
- bandspeed = Fpclk/16/value;
- CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, BIT_LCR_DLAB );
- CH438WriteReg(offsetadd[num]|REG_DLL_ADDR, (uint8_t)bandspeed);
- CH438WriteReg(offsetadd[num]|REG_DLM_ADDR, (uint8_t)(bandspeed>>8));
- printf("bandrate: %d\n", bandspeed);
- printf("DLM: %d\n", CH438ReadReg(offsetadd[num]|REG_DLM_ADDR));
- printf("DLL: %d\n", CH438ReadReg(offsetadd[num]|REG_DLL_ADDR));
- }
- void CH438_UARTInit(unsigned char num)//初始化 未使用到
- {
- CH438_SetBandrate(num, 9600); /* CH438串口1波特率设置 */
- CH438_TranConfig(num); /* CH438串口1数据格式配置及FIFO大小 */
- }
- //发送数据
- void CH438_SendDatas(unsigned char num, unsigned char* sendbuff,unsigned char len)
- {
- do
- {
- while((CH438ReadReg(offsetadd[num]|REG_LSR_ADDR)&BIT_LSR_THRE)==0); //LSR->THRE==1 保持寄存器空
- CH438WriteReg(offsetadd[num]|REG_THR_ADDR,*sendbuff++);
- }while(--len);
- }
- //接收数据
- unsigned char CH438_RecvDatas(unsigned char num, unsigned char* revbuff)
- {
- uint8_t len=0;
- uint8_t *p_rev;
- p_rev = revbuff;
- while( ( CH438ReadReg( offsetadd[num]|REG_LSR_ADDR ) & BIT_LSR_DATARDY ) == 0 ); /*等待数据准备好 */
- while((CH438ReadReg(offsetadd[num]|REG_LSR_ADDR)&BIT_LSR_DATARDY)) //LSR->DATARDY==1
- {
- *p_rev = CH438ReadReg(offsetadd[num]|REG_RBR_ADDR);
- p_rev++;
- len++;
- }
- return len;
- }
- void CH438_TranConfig(unsigned char num)
- {
- /* 发送数据格式:8位数据,无校验,1个停止位 */
- CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0);
- /* 设置FIFO模式,触发点为112字节 */
- CH438WriteReg(offsetadd[num]|REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN);
- CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,CH438ReadReg(offsetadd[num]|REG_FCR_ADDR)| BIT_FCR_TFIFORST|BIT_FCR_RFIFORST);
- }
- void CH438_INTConfig(unsigned char num)
- {
- /* 注意: CH438打开BIT_IER_IETHRE中断(0->1),会产生一个发生空中断 */
- CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV );
- CH438_CheckIIR(num);
- CH438WriteReg(offsetadd[num]|REG_MCR_ADDR, BIT_MCR_OUT2 | BIT_MCR_RTS | BIT_MCR_DTR);//可以产生一个实际的中断
- }
- void CH438_AutoHFCtrl(unsigned char num)
- {
- CH438WriteReg( offsetadd[num]|REG_MCR_ADDR, BIT_MCR_AFE | BIT_MCR_OUT2 | BIT_MCR_RTS );/* 设置MCR寄存器的AFE和RTS为1 */
- }
- //中断处理函数
- void EXTI1_IRQHandler()
- {
- u8 gInterruptStatus;
- u8 InterruptStatus;
- u8 i;
- static u8 j ;
- if(EXTI_GetITStatus(EXTI_Line1)!= RESET)
- {
- gInterruptStatus = CH438ReadReg( REG_SSR_ADDR );
- if(!gInterruptStatus)
- {
- EXTI_ClearITPendingBit(EXTI_Line1);
- return ;
- }
- for(i=0; i<8; i++)
- {
- if( gInterruptStatus & Interruptnum[i] ) /* 检测哪个串口发生中断 */
- {
- InterruptStatus = CH438ReadReg( offsetadd[i] | REG_IIR_ADDR ) & 0x0f; /* 读串口的中断状态 */
- switch( InterruptStatus )
- {
- case INT_NOINT: /* 没有中断 */
- break;
- case INT_THR_EMPTY: /* THR空中断 */
- break;
- case INT_RCV_OVERTIME: /* 接收超时中断 */
- RevLen = CH438_RecvDatas(i, Revbuff);
- CH438_SendDatas(i, Revbuff, RevLen);
- break;
- case INT_RCV_SUCCESS: /* 接收数据可用中断 */
- RevLen = CH438_RecvDatas(i, Revbuff);
- CH438_SendDatas(i, Revbuff, RevLen);
- break;
- case INT_RCV_LINES: /* 接收线路状态中断 */
- CH438ReadReg( offsetadd[i] | REG_LSR_ADDR );
- break;
- case INT_MODEM_CHANGE: /* MODEM输入变化中断 */
- CH438ReadReg( offsetadd[i] | REG_MSR_ADDR );
- break;
- default:
- break;
- }
- }
- }
- EXTI_ClearITPendingBit(EXTI_Line1);
- }
- }
- void CH438_RegTEST(unsigned char num)//测试使用的函数
- {
- printf("current test serilnum: %d \r\n",(unsigned short)offsetadd[num]);
- printf("IER: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_IER_ADDR));//?IER
- printf("IIR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_IIR_ADDR));//?IIR
- printf("LCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_LCR_ADDR));//?LCR
- printf("MCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_MCR_ADDR));//?MCR
- printf("LSR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_LSR_ADDR));//?LSR
- printf("MSR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_MSR_ADDR));//?MSR
- //CH438WriteReg(offsetadd[num] | REG_SCR_ADDR, 0x78);
- printf("SCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_SCR_ADDR));//?SCR
- printf("FCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_FCR_ADDR));//?SCR
- }
- //串口初始化函数 输入参数 串口号和波特率
- void CH438_Uart_Init(unsigned char num,unsigned long value)
- {
- uint8_t dlab=0;
- uint16_t bandspeed;
- dlab = CH438ReadReg(offsetadd[num]|REG_IER_ADDR);
- dlab &= 0xDF;
- CH438WriteReg(offsetadd[num]|REG_IER_ADDR, dlab);
- dlab = CH438ReadReg(offsetadd[num]|REG_LCR_ADDR);
- dlab |= 0x80; //置LCR寄存器DLAB位为1
- CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, dlab);
- bandspeed = Fpclk/16/value;
- CH438WriteReg(offsetadd[num]|REG_DLL_ADDR, (uint8_t)bandspeed);
- CH438WriteReg(offsetadd[num]|REG_DLM_ADDR, (uint8_t)(bandspeed>>8));
- dlab &= 0x7F; //置IIR寄存器DLAB位为0
- CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, dlab);
- CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN );
- CH438WriteReg(offsetadd[num]|REG_LCR_ADDR,BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0 );
- CH438WriteReg(offsetadd[num]|REG_IER_ADDR,BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV);
- CH438WriteReg(offsetadd[num]|REG_MCR_ADDR,BIT_MCR_OUT2 | BIT_MCR_RTS | BIT_MCR_DTR);
- CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,CH438ReadReg(offsetadd[num]|REG_FCR_ADDR)| BIT_FCR_TFIFORST|BIT_FCR_RFIFORST);
- }