Max32630(二)——串口+RTC+MX25
[复制链接]
许久没有发第二贴,今日再次分享下我与MX32630那些说不清道不明的事儿。
首先,发第一帖电灯后,论坛网友说程序下到开发板后灯不亮,而我测试时候灯也是亮的,这里就开始了一个说不清道不明的事儿了;
我再次把程序写如开发板,复位后,确实灯不亮了,几番重复后,依然无果;
于是从mbed上把LED的电灯程序编译出bin文件下载到开发板,这时灯亮了;
而在把我程序烧到开发板,灯也是亮的,但是如果重新上电,灯就有不亮了,这里不得不怀疑我程序有问题了;
从原理图到开发板各种找问题,都没有找到问题;
我按照mbed上代码初始化max14690,也不行,这里不知道有没有大神能解答下.....
mbed代码:
int MAX32630FTHR::init(vio_t hdrVio)
{
// Override the default values
max14690.ldo2Millivolts = 3300;
max14690.ldo3Millivolts = 3300;
max14690.ldo2Mode = MAX14690::LDO_ENABLED;
max14690.ldo3Mode = MAX14690::LDO_ENABLED;
max14690.monCfg = MAX14690::MON_HI_Z;
// Note that writing the local value does directly affect the part
// The buck-boost regulator will remain off until init is called
// Call init to apply all settings to the PMIC
if (max14690.init() == MAX14690_ERROR) {
printf("Error initializing MAX14690");
}
.....
}
我的mx14690初始化代码:
const max14690_cfg_t max14690_cfg2 = {
.ldo2mv = 3300, /**< 3.3v in mV, connected to VDDB */
.ldo2mode = MAX14690_LDO_ENABLED, /**< Enalbe LDO2 when +5v is present on VBUS */
.ldo3mv = 3300, /**< 3.3v is L3OUT -- optional */
.ldo3mode = MAX14690_LDO_ENABLED /**< Enable the LDO. */
};
void LDO_Init(void)
{
MAX14690_Init(&max14690_cfg2);
MAX14690_MuxSet(MAX14690_MUX_SEL_HIZ,MAX14690_MUX_DIV_4);
}
几乎是按照mbed的一样配置了,但是仍然不行;
第二个事儿,我使用模拟SPI驱动OLED显示屏,显示驱动也是在STM32F4上无误的,但是移植到max32630上不行,折腾几天未果;
STM32F4代码:
#define OLED_CS_PORT GPIOA
#define OLED_CS_PIN GPIO_Pin_0
#define OLED_DC_PORT GPIOA
#define OLED_DC_PIN GPIO_Pin_1
#define OLED_RST_PORT GPIOA
#define OLED_RST_PIN GPIO_Pin_4
#define OLED_SDA_PORT GPIOC
#define OLED_SDA_PIN GPIO_Pin_1
#define OLED_SCL_PORT GPIOB
#define OLED_SCL_PIN GPIO_Pin_0
#define OLED_CS(X) X?GPIO_SetBits(OLED_CS_PORT, OLED_CS_PIN):GPIO_ResetBits(OLED_CS_PORT, OLED_CS_PIN) //X为1时对应GPIO端口输出高电平,X为0时对应GPIO端口输出低电平
#define OLED_RST(X) X?GPIO_SetBits(OLED_RST_PORT, OLED_RST_PIN):GPIO_ResetBits(OLED_RST_PORT, OLED_RST_PIN)
#define OLED_DC(X) X?GPIO_SetBits(OLED_DC_PORT, OLED_DC_PIN):GPIO_ResetBits(OLED_DC_PORT, OLED_DC_PIN)
#define OLED_D0(X) X?GPIO_SetBits(OLED_SDA_PORT, OLED_SDA_PIN):GPIO_ResetBits(OLED_SDA_PORT, OLED_SDA_PIN)
#define OLED_D1(X) X?GPIO_SetBits(OLED_SCL_PORT, OLED_SCL_PIN):GPIO_ResetBits(OLED_SCL_PORT, OLED_SCL_PIN)
void Delay(uint32_t nCount)
{
u8 i;
for(; nCount != 0; nCount--)
{
for(i=0; i<10; i++);
}
}
//向SSD1306写入一个字节
//dat:要写入的数据或者命令
//cmd:数据或者命令 命令:0 数据:1
/* SPI写数据/命令
* Mode :O:写命令 1:写数据
* data :数据/命令
*
*/
void SPI_Write(char data, int Mode)
{
int i = 0;
if(Mode)
{
OLED_DC(1); //DC引脚输入高,表示写数据
}
else
{
OLED_DC(0); //DC引脚输入低,表示写命令
}
OLED_CS(0); //CS引脚输入低,片选使能
for(i = 0; i < 8; i++)
{
OLED_D0(0); //D0引脚输入低
if(data & 0x80) //判断传输的数据最高位为1还是0
{
OLED_D1(1); //D1引脚输入高
}
else
{
OLED_D1(0); //D1引脚输入低
}
OLED_D0(1); //D1引脚输入高
data <<= 1; //将数据左移一位
}
OLED_DC(0); //DC引脚输入低
OLED_CS(1); //CS引脚输入高,片选失能
}
/* 设置OLED屏的显示坐标
* X : 表示OLED的水平坐标(0—127)
* Y : 表示OLED的页(0—7)
*
*/
void OLED_Coord(unsigned char x, unsigned char y)
{
SPI_Write((0xb0+(y & 0x0f)), 0); //设置OLED显示的页
SPI_Write((((x & 0xf0)>>4) | 0x10), 0);//设置OLED水平坐标的高4位
SPI_Write((x & 0x0f)|0x01, 0); //设置OLED水平坐标的低4位
}
/*
* 清除OLED的显示
*
*
*/
void OLED_Clear(void)
{
int i = 0, j = 0;
for(i = 0; i < 8; i++)
{
OLED_Coord(0, i);
for(j = 0; j < 128; j++)
{
SPI_Write(0x00, 1);
}
}
}
/* 关闭OLED显示
*
*
*/
void OLED_Display_Off(void)
{
//电荷泵设置(初始化时必须打开,否则看不到显示)
SPI_Write(0x8D, 0);
SPI_Write(0x10, 0);//bit2 0:关闭 1:打开
SPI_Write(0xAE, 0);//0xAE:关闭显示
}
/*
* 开启OLED显示
*
*/
void OLED_Display_On(void)
{
//电荷泵设置(初始化时必须打开,否则看不到显示)
SPI_Write(0x8D, 0);
SPI_Write(0x14, 0);//bit2 0:关闭 1:打开
SPI_Write(0xAF, 0);//0xAF:开显示
}
/* OLED显示参数的初始化
*
*
*
*/
void OLED_Init(void)
{
OLED_RST(1);
Delay(100);
OLED_RST(0);
Delay(100);
OLED_RST(1);
SPI_Write(0xAE, 0);//0xAE:关显示
SPI_Write(0x00, 0);//设置低列地址
SPI_Write(0x10, 0);//设置高列地址
//设置行显示的开始地址(0-63)
//40-47: (01xxxxx)
SPI_Write(0x40, 0);
//设置对比度
SPI_Write(0x81, 0);
SPI_Write(0xff, 0);//这个值越大,屏幕越亮(和上条指令一起使用)(0x00-0xff)
SPI_Write(0xA1, 0);//0xA1: 左右反置, 0xA0: 正常显示(默认0xA0)
SPI_Write(0xC8, 0);//0xC8: 上下反置, 0xC0: 正常显示(默认0xC0)
//0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
//0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
SPI_Write(0xA6, 0);
SPI_Write(0xA8, 0);//设置多路复用率(1-64)
SPI_Write(0x3F, 0);//(0x01-0x3f)(默认为3f)
//设置显示抵消移位映射内存计数器
SPI_Write(0xD3, 0);
SPI_Write(0x00, 0);//(0x00-0x3f)(默认为0x00)
//设置显示时钟分频因子/振荡器频率
SPI_Write(0xD5, 0);
//低4位定义显示时钟(屏幕的刷新时间)(默认:0000)分频因子= [3:0]+1
//高4位定义振荡器频率(默认:1000)
SPI_Write(0x80, 0);//
//时钟预充电周期
SPI_Write(0xD9, 0);
SPI_Write(0xF1, 0);//[3:0],PHASE 1; [7:4] PHASE 2
//设置COM硬件应脚配置
SPI_Write(0xDA, 0);
SPI_Write(0x12, 0);//[5:4] 默认:01
SPI_Write(0xDB, 0);//
SPI_Write(0x40, 0);//
//设置内存寻址方式
SPI_Write(0x20, 0);
//00: 表示水平寻址方式
//01: 表示垂直寻址方式
//10: 表示页寻址方式(默认方式)
SPI_Write(0x02, 0);//
//电荷泵设置(初始化时必须打开,否则看不到显示)
SPI_Write(0x8D, 0);
SPI_Write(0x14, 0);//bit2 0:关闭 1:打开
//设置是否全部显示 0xA4: 禁止全部显示
SPI_Write(0xA4, 0);
//0xA6: 表示正常显示(在面板上1表示点亮,0表示不亮)
//0xA7: 表示逆显示(在面板上0表示点亮,1表示不亮)
SPI_Write(0xA6, 0);//
SPI_Write(0xAF, 0);//0xAF:开显示
SPI_Write(0xAF, 0);//0xAF:开显示
OLED_Clear();
}
/* 显示汉字
* x:表示显示的水平坐标
* y: 表示显示的垂直坐标
* *p: 表示要显示汉字模组的首地址
*/
void OLED_ShowChinese(int x, int y, const unsigned char *p)
{
int i = 0;
OLED_Coord(x, y);
for(i = 0; i < 32; i+=2)
{
SPI_Write(p[i], 1);
}
OLED_Coord(x, y+1);
for(i = 1; i < 32; i+=2)
{
SPI_Write(p[i], 1);
}
}
/* 显示ASCII
* x:表示显示的水平坐标
* y: 表示显示的垂直坐标
* *p: 表示要显示汉字模组的首地址
*/
void OLED_ShowChar(int x, int y, const unsigned char p)
{
int i = 0;
OLED_Coord(x, y);
if(p < 33)
return;
for(i = 0; i < 16; i+=2)
{
SPI_Write(F8X16[p-32][i], 1);
}
OLED_Coord(x, y+1);
for(i = 1; i < 16; i+=2)
{
SPI_Write(F8X16[p-32][i], 1);
}
} 复制代码
而移植过来的就改了IO口的操作;代码如下:
#define OLED_CS(X) X?OLED_CS_SET():OLED_CS_RESET() //X为1时对应GPIO端口输出高电平,X为0时对应GPIO端口输出低电平
#define OLED_RST(X) X?OLED_RST_SET():OLED_RST_RESET()
#define OLED_DC(X) X?OLED_DC_SET():OLED_DC_RESET()
#define OLED_D0(X) X?OLED_SDA_SET():OLED_SDA_RESET()
#define OLED_D1(X) X?OLED_SCL_SET():OLED_SCL_RESET()
const gpio_cfg_t OLED[] = {
{ PORT_5, PIN_3, GPIO_FUNC_GPIO, GPIO_PAD_NORMAL },
{ PORT_3, PIN_3, GPIO_FUNC_GPIO, GPIO_PAD_NORMAL },
{ PORT_3, PIN_2, GPIO_FUNC_GPIO, GPIO_PAD_NORMAL },
{ PORT_3, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_NORMAL },
{ PORT_3, PIN_5, GPIO_FUNC_GPIO, GPIO_PAD_NORMAL },
};
void OLED_CS_SET(void)
{
GPIO_OutSet(&OLED[0]);
}
void OLED_CS_RESET(void)
{
GPIO_OutClr(&OLED[0]);
}
void OLED_DC_SET(void)
{
GPIO_OutSet(&OLED[1]);
}
void OLED_DC_RESET(void)
{
GPIO_OutClr(&OLED[1]);
}
void OLED_RST_SET(void)
{
GPIO_OutSet(&OLED[2]);
}
void OLED_RST_RESET(void)
{
GPIO_OutClr(&OLED[2]);
}
void OLED_SDA_SET(void)
{
GPIO_OutSet(&OLED[3]);
}
void OLED_SDA_RESET(void)
{
GPIO_OutClr(&OLED[3]);
}
void OLED_SCL_SET(void)
{
GPIO_OutSet(&OLED[4]);
}
void OLED_SCL_RESET(void)
{
GPIO_OutClr(&OLED[4]);
}
复制代码
这里不知道是IO口模式不正确还是什么原因,不过还没用示波器看波形,下周看下波形;
接着就是串口,这个比较简单,调通了,不过如果大家要用printf打印信息的话,需要改一个东西:
board.h文件下
#ifndef CONSOLE_UART
#define CONSOLE_UART 1 /**< UART instance to use for the serial console. */
#endif
需要把串口改为1,因为 开发板上串口1与DAP调试板相连,其他就没什么问题了,程序就可以直接用printf打印看数据了
附上代码:
#define BUFF_SIZE 1
/***** Globals *****/
volatile int read_flag1;
volatile int read_flag2;
uint8_t rxdata1[BUFF_SIZE];
uint8_t rxdata2[BUFF_SIZE];
/***** Functions *****/
/******************************************************************************/
void read_cb1(uart_req_t* req, int error) {
read_flag1 = error;
}
/******************************************************************************/
void read_cb2(uart_req_t* req, int error) {
read_flag2 = error;
}
/******************************************************************************/
void UART1_IRQHandler(void) {
UART_Handler(MXC_UART1);
}
void UART2_IRQHandler(void) {
UART_Handler(MXC_UART2);
}
uart_req_t read_req2;
uart_req_t read_req1;
int Usart2_Init(void)
{
int error;
sys_cfg_uart_t sys_cfg;
NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(2));
NVIC_DisableIRQ(MXC_UART_GET_IRQ(2));
NVIC_SetPriority(MXC_UART_GET_IRQ(2), 1);
NVIC_EnableIRQ(MXC_UART_GET_IRQ(2));
uart_cfg_t cfg;
cfg.parity = UART_PARITY_DISABLE;
cfg.size = UART_DATA_SIZE_8_BITS;
cfg.extra_stop = 1;
cfg.cts = 0;
cfg.rts = 0;
cfg.baud = 9600;
sys_cfg.clk_scale = CLKMAN_SCALE_AUTO;
sys_cfg.io_cfg = (ioman_cfg_t)IOMAN_UART(1, IOMAN_MAP_A, IOMAN_MAP_A, IOMAN_MAP_A, 1, 1, 1);
// Wait for the console UART to finish
while (UART_Busy(MXC_UART_GET_UART(2))) {
}
error = UART_Init(MXC_UART2, &cfg, &sys_cfg);
UART_Init(MXC_UART_GET_UART(2), &console_uart_cfg, NULL);
if (error != E_NO_ERROR) {
printf("Error initializing UART2 %d\n", error);
while (1) {
}
} else {
printf("UART2 Initialized\n");
}
if (error != E_NO_ERROR) {
printf("Error initializing UART2 %d\n", error);
while (1) {
}
} else {
printf("UART2 Initialized\n");
}
read_req2.data = rxdata2;
read_req2.len = BUFF_SIZE;
read_req2.callback = read_cb2;
read_flag2 = 1;
return E_NO_ERROR;
}
void Usart2_Recive(void)
{
int error;
error = UART_ReadAsync(MXC_UART2, &read_req2);
if (error != E_NO_ERROR) {
// printf("Error starting async read %d\n", error);
// while (1) {
// }
}
if(read_flag2 == E_NO_ERROR)
{
Kfifo_Put(&Gpsfifo,rxdata2,1);
printf("%s",rxdata2);
memset(rxdata2, 0x0, BUFF_SIZE);
read_flag2 = 1;
}
}
void Usart1_Recive(void)
{
int error;
error = UART_ReadAsync(MXC_UART1, &read_req1);
if (error != E_NO_ERROR) {
// printf("Error starting async read %d\n", error);
// while (1) {
// }
}
if(read_flag1 == E_NO_ERROR)
{
printf("%s",rxdata1);
memset(rxdata1, 0x0, BUFF_SIZE);
read_flag1 = 1;
}
}
int CONSOLE_UART_Init(void)
{
int error;
uart_req_t read_req;
sys_cfg_uart_t sys_cfg;
NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(1));
NVIC_DisableIRQ(MXC_UART_GET_IRQ(1));
NVIC_SetPriority(MXC_UART_GET_IRQ(1), 1);
NVIC_EnableIRQ(MXC_UART_GET_IRQ(1));
uart_cfg_t cfg;
cfg.parity = UART_PARITY_DISABLE;
cfg.size = UART_DATA_SIZE_8_BITS;
cfg.extra_stop = 1;
cfg.cts = 0;
cfg.rts = 0;
cfg.baud = CONSOLE_BAUD;
sys_cfg.clk_scale = CLKMAN_SCALE_AUTO;
sys_cfg.io_cfg = (ioman_cfg_t)IOMAN_UART(1, IOMAN_MAP_A, IOMAN_MAP_A, IOMAN_MAP_A, 1, 1, 1);
// Wait for the console UART to finish
while (UART_Busy(MXC_UART_GET_UART(CONSOLE_UART))) {
}
error = UART_Init(MXC_UART1, &cfg, &sys_cfg);
UART_Init(MXC_UART_GET_UART(CONSOLE_UART), &console_uart_cfg, NULL);
if (error != E_NO_ERROR) {
printf("Error initializing UART1 %d\n", error);
while (1) {
}
} else {
printf("UART1 Initialized\n");
}
if (error != E_NO_ERROR) {
printf("Error initializing UART1 %d\n", error);
while (1) {
}
} else {
printf("UART1 Initialized\n");
}
read_req1.data = rxdata1;
read_req1.len = BUFF_SIZE;
read_req1.callback = read_cb1;
read_flag1 = 1;
return E_NO_ERROR;
}
复制代码
最后就是RTC了,这个也比较简单,把例子中的代码移植过来,稍微更改下就可以了;
附上代码:
不过这个RTC也是只有秒的计数值,还需要自己计算年月日。
好了,就到这儿,周末公司组织活动,下周继续分析问题;祝大家有一个愉快的周末