目录
一、串口打印
新板的串口为UART3,默认配置的是UART1.需要修改以下两处完成UART3的串口打印
#ifdef DEBUG
GPIOA_SetBits(bTXD3);
GPIOA_ModeCfg(bTXD3, GPIO_ModeOut_PP_5mA);
UART3_DefInit();
这个是用来选择串口打印的宏定义处,只需要将DEBUG=x的x改变即可。
printf 可以勾选这个配置,那么就不需要加换行。
串口配置相关文章:
有关MounRiver打印问题(转行符和浮点数) - Risc5_BLE - 博客园
有关MounRiver更改打印串口 - Risc5_BLE - 博客园
二、SD卡
2.1:SD卡容量读取
SD卡用的是Zetta(澜智)_SD NAND ZDSD01GLGEAG 1Gbit(128MByte),调试时SD卡初始化一直失败,用示波器读取CS\CK\MOSI均有波形输入,MISO无波形输出后排除是因为SD卡虚焊问题;
利用FATFS文件系统读取,测试代码如下;
if(events & FS_SPI_INI_EVT)
{
if(fnSdInit())
{
PRINT("SD Card Error!\n");
}
else
{
uint32 uSize;
PRINT("SD Card Ok!\n");
uSize = fnSdGetSectorCount();
PRINT("SectorCounts=%d\n",uSize);
PRINT("容量=%dM\n",uSize>>11);
// tmos_set_event(fs_test_TaskID,FS_TEST_EVT);
}
tmos_start_task(fs_test_TaskID,FS_SPI_INI_EVT,1000);
return (events ^ FS_SPI_INI_EVT);
}
FATFS一次是读写一个块的数据一个块512B,247808个块/2/1024 = 121M,
用MSC模拟U盘后得到的内存大小通上面计算一致
2.2 :由模拟SPI读写改成硬件SPI
2.2.1 模拟SPI
CH582只有一个硬件SPI只有一个SPI0,V1.0的开发板版本么没有注意SD卡槽连接的是SPI1口。
V1.0的开发板用的是IO模拟SPI速率较慢,不用在初始化SD卡时SPI速率要降低初始化完成后再将SPI速率提高(SD卡的初始化速度不能大于400KHz,最高不超过15MHZ ????还有待确认);
速率读写测试函数
if(FR_OK == fr)
{
fr = f_open(file, "0:2B.WAV", FA_READ);
uOrgTick = TMOS_GetSystemClock();
do{
if(FR_OK != f_read(file, pFatBuf, 512, &br))
{
PRINT("fr ng!\n");
break;
}
uLens += br;
}
while(uLens < 1024*1024*4);
f_close(file);
uNewTick = TMOS_GetSystemClock();
PRINT("tick=%d,len=%d\n",uNewTick - uOrgTick, uLens);
PRINT("speed=%d B/S\n",uLens*100/((uNewTick - uOrgTick)/16));
}
模拟SPI读文件速率如下
模拟SPI写入速率
文的读取写入主要靠SPI向SD卡发送命令,主要的函数是SD卡发送命令函数fnSdSendCmd(uint8 ucCmd, uint32 uArg, uint8 ucCrc7)。而发送命令函数主要又是由模式SPI发送读写一个字节函数fnRwSpiSdByte(uint8 ucTxData)(SPI的主机发一个数据从机就回一个数据)
inline static void fnSetSck(void)
{
GPIOA_SetBits(GPIO_Pin_13);
}
inline static void fnClrSck(void)
{
GPIOA_ResetBits(GPIO_Pin_13);
}
inline static void fnSetMosi(void)
{
GPIOA_SetBits(GPIO_Pin_14);
}
inline static void fnClrMosi(void)
{
GPIOA_ResetBits(GPIO_Pin_14);
}
inline static uint32_t fnRdMiso(void)
{
return GPIOA_ReadPortPin(GPIO_Pin_15);
}
uint8 fnRwSpiSdByte(uint8 ucTxData)
{
uint8 ucVal = 0;
for(int8_t i = 7; i >= 0 ; i--)
{
fnClrSck(); //CLK低
if(ucTxData& (1<<i))
{
fnSetMosi(); //发1
}
else
{
fnClrMosi();//发0
}
fnSetSck(); //CLK高
if(fnRdMiso()) //读一个bit
{
ucVal |= 1<<i;
}
}
return ucVal; //读回的数据
}
2.2.2 模拟SPI
硬件的SPI不需要模拟SCK,硬件直接产生,并读写数据,原本的SPI0库函数只有读一个字和写一个字的库函数,所以需要增加一个读写一个字的函数。
__HIGH_CODE
uint8 fnRwSpiSdByte(uint8 ucTxData)
{
R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
R8_SPI0_BUFFER = ucTxData; //发送的date
while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
return ( R8_SPI0_BUFFER ); //返回的data
}
硬件SPI读文件速率如下 较模拟 SPI速率快一倍
2.2.3 SPI速率问题
在初始化SD卡时SPI速率要降低初始化完成后再将SPI速率提高,
SPI0_CLKCfg(4); = 60/4 = 15MHz ,当分频系数小于4时SD卡读取会出现失败,具体原因??
相关参考文章:
MSP430 SD卡SPI读写操作(2) —— SD卡SPI操作流程_Zn的博客-CSDN博客
FATfs源码解析_天使画笔的博客-CSDN博客_fatfs源码
三、触摸
触摸Touch:参照官方例程库
参考文章:电容触摸按键
四、TMR定时器 (22.11.1)
用两定时器生成个8位的PWM组成16位的PWM,之前的方案是一个TMR加两个PWM。
现存在问题:
1:TMR定时器的配置还没搞清楚,PWM频率为什么要越高越好,以及输入数据占空比的数据处理。
2:遇到问题在用文件名播放WAV时,给播放任务发送消息时忘记将消息事件位清除掉,导致数据流断流,这个问题查找了好几天,自己还缺乏快速定位问题的能力。以及要懂得先做哪一步再做下一步更步要验证。
3:代码要健壮,自己编写的消息结构还不好。
相关文章:【电子电路】(1)PWM转DAC如何实现_小石头有大内涵的博客-CSDN博客_pwm转dac
4:今天改用之前的方案即一个定时器和两个用定时器产生的PWM波播放WAV,PWM频率可以调到60M/256=234Khz,但是播放音乐时仍然存在噪音234Khz的底噪。经过排查发现不用通过USB口供电用电池供电底噪音就没有了播放的音乐正常。遂发现问题的在供电充电这一块(具体原因待...).改回原来的两个TMR产生的32KhzPWM用电池供电播放正常,且PWM波形也平滑,用USB供电PWM波形有问题。找到问题点。(22.11.2)
5:用USB供电产生底噪的原因分析(自己分析)可能是噪声耦合导致(一个芯片对另一个芯片产生的干扰)一个是输入的PWM波236K,一个是运放输出端的耦合噪声240K,解决办法:运放引脚加一个旁路电容、电源线上加一个去耦合电容。(22.11.3)。
6.用USB供电产生底噪的原因分析曾工给出的解释:通过USB供电,充电芯片供电不做导致。上述问题并非产生的是底噪,后面不管是USB供电还是电池供电输入PWM,功放输出端都有上述波形输出。是因为用USB是给充电模块供电,充电模块的输出个板子供电,充电模块输出的电流小不足以驱动功放模块的电流输出,之前PWM高电平的抖动,和播放时板子突然断电重启因为电流不够导致,因此在调试的时候应该插上电池。。(22.11.4)
参考文章:
只知道芯片旁边加一个电容是不够的!一个简单的小实验,让你马上明白“去耦电容”和“旁路电容”的工作原理_哔哩哔哩_bilibili
五、BLE(22.11.2)
测试BLE1S的广播间隔和仅开Touch的待机功耗(22.11.3)
修改广播间隔为1s
// What is the advertising interval when device is discoverable (units of 625us, 80=50ms)
#define DEFAULT_ADVERTISING_INTERVAL 1600
//4、设置广告间隔 (units if 0.625us)
{
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
// Set advertising interval
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
}
从测试数据看数值还是偏大,问题点暂时未知
相关参考文章:
低功耗蓝牙BLE之修改广播间隔等参数_枫之星雨的博客-CSDN博客
【BLE】CC2541之电池电量服务_甜甜的大香瓜的博客-CSDN博客_ble电量
蓝牙4.0 BLE peripheral 广播设置_si_zhou_qun_84342712的博客-CSDN博客
终于降了!!!蓝牙低功耗芯片CH579超低功耗0.2uA!!! - - 21ic电子技术开发论坛
请问为什么增加了hid键盘的广播间隔时间,功耗却没有变? - 沁恒微电子社区
BLE广播间隔和连接间隔(CH582) - SweetTea_lllpc - 博客园
六、ADC采样
6.1
可以考虑GPIO中断的方法检测插入、开启任务。(暂时用任务循环触发)
遇到问题:数组元素计算问题,
问题原因用prinf函数直接打印函数返回值,用函数返回值运算导致:
C语言:
打印出来的结果是Sunday Sunday、
printf的参数压栈顺序是自右至左, 也就是那两个函数调用是先执行右边的后执行左边的,然后printf才会打印出内容。
然后就是get_day()这个函数是不可重入函数,函数的返回值是buf这个静态数组的的首地址。而static变量不管声明在哪,他的空间都是分配在全局静态区的。也就是在整个程序声明周期中get_day()返回的地址永远都是buf的首地址(不会改变)。
所以你调用这个printf后, 实际上buf这个数组里面存的是最后一个执行的结果。也就是get_day(0).所以得到的结果是两个sunday
printf的小例子_mal327的博客-CSDN博客
(22.11.4)
参考文章:
深刻理解GPIO(上拉输入、下拉输入、模拟输入、浮空输入,开漏输出,推挽输出的区别,以STM32为例)_没有余地没有余地的博客-CSDN博客_上拉输入
【BLE 5.3无线MCU CH582】8、adc采样(内部bat、内部温度,外部输入) - 国产芯片交流 - 电子工程世界-论坛
6.2完成ADC对于电压值的采样:
存在问题,在计算时要注意数据位计算的先后
ADCVal先÷2048再×1000,导致数据溢出结果错误,与实际值不符。应该先*1000,避免数据错误(22.11.6)
充电芯片相关信息:
矽源特ME4074是一款完整的单节锂离子电池用恒定电流/恒定电压线性充电芯片_输出_功能_模式
七、低功耗
7.1遇见问题:在使用Peripheral例程调试低功耗时将DEBUG宏, 关闭DEBUG 宏定义,程序不能正常运行。
原因:DEBUG宏定义,其值代表printf函数调用的putchar中,选用哪一个物理串口进行输出。由于putchar没有实际串口被选择,可能导致printf函数无法返回。 Peripheral_Init();中有打印信息,关闭DEBUG就会导致printf函数无法返回。将里面打印信息注释即可。(22.11.14)
Peripheral_Init()10S广播间隔在1.15mA
7.2 之前一直没有进行电源控制的管理,在程序中打开的HAL_SLEEP宏定义,是配置系统进行睡眠模式,其唤醒由TMOS自动管理。配置电源管理不仅仅是简单的将全部端口配置为输入下拉模式(这样空跑单片机是还运行的)没有进行任何的电源管理。今天测试用571的最小系统板拆除了芯片是多余的外设模块包括1117降压芯片用3.3V外设电源直接供电。验证不同功耗开销。
下面为刷写Peripheral不同的广播间隔的功耗:
50ms广播间隔 广播模式 | 连接后 |
0.56mA | 0.17mA |
1s广播间隔 广播模式 | 连接后 |
2.5uA(后测为5uA) | 120uA |
上述初步排除之前582M完整版本功耗一直在1.2mA是软件问题,下一步检查582M板子上的问题点(22.11.15)。
7.3之前582M完整版本功耗一直在1.2mA是软件配置问题,IO口配置的全部为输入上拉模式,导致漏电流。
将IO改为输入下拉,和部分需要的输入上拉后整机待机功耗下降下来。
广播时的待机电流为5-6uA:
广播时的功耗1S的广播间隔30uA(4.2v/680Ω/100/2)估算值。
(22.11.17)
4:温度检测
CH573F 使用LSI时如何关闭外部晶振 - 沁恒微电子社区 (wch.cn)
CH579 CH573 CH582 芯片使用知识分享目录 - debugdabiaoge - 博客园 (cnblogs.com)