This commit is contained in:
王绪洁 2025-03-12 13:34:16 +08:00
parent 4666615d9f
commit 0b9a30eb0e
2 changed files with 195 additions and 1 deletions

View File

@ -1,6 +1,8 @@
#include "ch438q.h" #include "ch438q.h"
#include "fsmc.h" #include "fsmc.h"
#define CH438_CLK 1843200 /* CH438的内部时钟频率默认外部晶振的12分频 */
const uint8_t offsetadd[] = { const uint8_t offsetadd[] = {
0x00, 0x00,
0x10, 0x10,
@ -22,12 +24,74 @@ const uint8_t Interruptnum[] = {
0x80, 0x80,
}; /* SSR寄存器中断号对应值 */ }; /* SSR寄存器中断号对应值 */
static void ch438_tranconfig(uint8_t uart_num);
static void ch438_set_baudrate(uint8_t uart_num, uint32_t baudrate);
/**
* @brief
*
* 811FIFO模式112
*
* @param uart_num
*/
void ch438_tranconfig(uint8_t uart_num)
{
// 设置串口通讯的格式8个数据位1个停止位1个校验位奇校验
ch438_write_reg(offsetadd[uart_num] | REG_LCR_ADDR, BIT_LCR_PAREN | BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0, 1);
/* 设置FIFO模式触发点为112个字节 */
ch438_write_reg(offsetadd[uart_num] | REG_FCR_ADDR, BIT_FCR_RECVTG0 | BIT_FCR_RECVTG1 | BIT_FCR_FIFOEN, 1);
}
/**
* @brief CH438 UART的波特率
*
* CH438 UART的波特率寄存器来设置指定UART的波特率
*
* @param uart_num UART编号
* @param baudrate
*/
static void ch438_set_baudrate(uint8_t uart_num, uint32_t baudrate)
{
uint8_t dlab = 0;
uint16_t bandspeed;
dlab = ch438_read_reg(offsetadd[uart_num] | REG_LCR_ADDR, 1);
dlab |= 0x80; // 置LCR寄存器的DLAB位为1
ch438_write_reg(offsetadd[uart_num] | REG_LCR_ADDR, dlab, 1);
bandspeed = CH438_CLK / 16 / baudrate;
ch438_write_reg(offsetadd[uart_num] | REG_DLL_ADDR, (uint8_t)bandspeed, 1);
ch438_write_reg(offsetadd[uart_num] | REG_DLM_ADDR, (uint8_t)(bandspeed >> 8), 1);
dlab &= 0x7F; // 置LCR寄存器的DLAB位为0
ch438_write_reg(offsetadd[uart_num] | REG_LCR_ADDR, dlab, 1);
}
/**
* @brief CH438寄存器写入数据
*
* CH438芯片的指定寄存器写入指定大小的数据
*
* @param addr
* @param data
* @param size
*/
void ch438_write_reg(uint8_t addr, uint8_t data, uint8_t size) void ch438_write_reg(uint8_t addr, uint8_t data, uint8_t size)
{ {
uint32_t *address = (uint32_t *)(0x60000000 + addr); uint32_t *address = (uint32_t *)(0x60000000 + addr);
HAL_SRAM_Write_8b(&hsram1, address, &data, size); HAL_SRAM_Write_8b(&hsram1, address, &data, size);
} }
/**
* @brief CH438的寄存器中读取数据
*
*
*
* @param addr
* @param size
*
* @return
*/
uint8_t ch438_read_reg(uint8_t addr, uint8_t size) uint8_t ch438_read_reg(uint8_t addr, uint8_t size)
{ {
uint8_t data = 0; uint8_t data = 0;
@ -48,3 +112,114 @@ void ch438_test(void)
reg_data[3] = ch438_read_reg(offsetadd[0] | REG_IIR_ADDR, 1); reg_data[3] = ch438_read_reg(offsetadd[0] | REG_IIR_ADDR, 1);
reg_data[4] = ch438_read_reg(offsetadd[0] | REG_LSR_ADDR, 1); reg_data[4] = ch438_read_reg(offsetadd[0] | REG_LSR_ADDR, 1);
} }
/**
* @brief UART
*
* UART设备
*
* @return
*/
void ch438_reset_all_uart(void)
{
for (uint8_t i = 0; i < 8; i++)
{
ch438_write_reg(offsetadd[CH438_UART0 + i] | REG_IER_ADDR, BIT_IER_RESET, 1);
}
}
/**
* @brief UART的电源
*
* UART的电源使UART进入低功耗模式
*
* @param uart_num UART编号03
*/
void ch438_close_uart(uint8_t uart_num)
{
ch438_write_reg(offsetadd[uart_num] | REG_IER_ADDR, BIT_IER_LOWPOWER, 1);
}
/**
* @brief UART串口
*
* CH438芯片上的所有UART串口
*
* CH438的IER寄存器使
* SLP使LOWPOWER使1
* 使UART串口进入休眠状态
*/
void ch438_close_all_uart(void)
{
ch438_write_reg(offsetadd[CH438_UART0] | REG_IER_ADDR, BIT_IER_LOWPOWER | BIT_IER_SLP, 1); // 数据手册描述SLP和LOWPOWER同时为1关闭时钟振荡器所有串口进入休眠
}
/**
* @brief UART通信
*
* UART端口
*
* @param uart_num UART端口号
* @param baudrate
*/
void ch438_init_uart(uint8_t uart_num, uint32_t baudrate)
{
ch438_tranconfig(uart_num);
ch438_set_baudrate(uart_num, baudrate);
}
/**
* @brief IIR
*
* UART编号读取并返回中断标识寄存器IIR
*
* @param uart_num UART编号UART接口
*
* @return IIR
*/
uint8_t ch438_check_iir_reg(uint8_t uart_num)
{
return ch438_read_reg(offsetadd[uart_num] | REG_IIR_ADDR, 1);
}
/**
* @brief CH438的配置
*
* CH438芯片的配置使
*
* @param uart_num UART编号UART通道
*/
void ch438_init_config(uint8_t uart_num)
{
/* CH438打开BIT_IER_IETHRE会产生一个发送空中断 */
ch438_write_reg(offsetadd[uart_num] | REG_IER_ADDR, BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV, 1);
ch438_check_iir_reg(uart_num);
ch438_write_reg(offsetadd[uart_num] | REG_MCR_ADDR, BIT_MCR_OUT2, 1);
}
void ch438_send_data(uint8_t uart_num, uint8_t *data, uint16_t len)
{
ch438_write_reg(offsetadd[uart_num] | REG_THR_ADDR, data[0], len);
}
uint8_t ch438_recv_data(uint8_t uart_num, uint8_t *data)
{
uint8_t data_len = 0;
uint8_t *receive_data;
receive_data = data;
while ((ch438_read_reg(offsetadd[uart_num] | REG_LSR_ADDR, 1) & BIT_LSR_DATARDY) == 0)
; // 等待数据准备好
while ((ch438_read_reg(offsetadd[uart_num] | REG_LSR_ADDR, 1) & BIT_LSR_DATARDY))
{
*receive_data = ch438_read_reg(offsetadd[uart_num] | REG_RBR_ADDR, 1);
receive_data++;
data_len++;
if (data_len == 112)
{
break;
}
}
return data_len;
}

View File

@ -109,8 +109,27 @@
#define CH438_IIR_FIFOS_ENABLED 0xC0 /* 起用FIFO */ #define CH438_IIR_FIFOS_ENABLED 0xC0 /* 起用FIFO */
typedef enum
{
CH438_UART0 = 0,
CH438_UART1,
CH438_UART2,
CH438_UART3,
CH438_UART4,
CH438_UART5,
CH438_UART6,
CH438_UART7,
} ch438_uart_e;
void ch438_write_reg(uint8_t addr, uint8_t data, uint8_t size); void ch438_write_reg(uint8_t addr, uint8_t data, uint8_t size);
uint8_t ch438_read_reg(uint8_t addr, uint8_t size); uint8_t ch438_read_reg(uint8_t addr, uint8_t size);
void ch438_test(void); void ch438_test(void);
void ch438_reset_all_uart(void);
void ch438_close_uart(uint8_t uart_num);
void ch438_close_all_uart(void);
void ch438_init_uart(uint8_t uart_num, uint32_t baudrate);
uint8_t ch438_check_iir_reg(uint8_t uart_num);
void ch438_init_config(uint8_t uart_num);
void ch438_send_data(uint8_t uart_num, uint8_t *data, uint16_t len);
uint8_t ch438_recv_data(uint8_t uart_num, uint8_t *data);
#endif #endif