牛卧堂MCU技术交流
标题:
N32903的ADC模块以一种时钟频率初始化后,能切换成另外一...
[打印本页]
作者:
匿名
时间:
2022-4-13 23:45
标题:
N32903的ADC模块以一种时钟频率初始化后,能切换成另外一...
大佬,您好!
N32903的ADC模块以一种时钟频率初始化后,能切换成另外一种时钟频率吗?
最近有一个应用:条码打印机。
在检测纸张的类型和尺寸的时候,希望ADC模块工作在500KHz左右;
在走纸和打印的时候,希望ADC模块工作在16MHz左右。
这样才能保证纸张检测准确度较高。
在使用中发现:当以500KHz初始化ADC模块,完成纸张类型和尺寸检测后,disable掉ADC模块,然后以16MHz的工作时钟频率初始ADC模块,然后工作在走纸和打印模式,
发现ADC模块仍然是工作在500KHz,导致走纸和打印报错。
希望能在这2种频率间来回切换。
不知道是芯片本身不支持这样操作呢,还是我的初始化操作有问题呢。
望得到你的帮助:我怎样才能解决这个问题。
谢谢!
作者:
arthur
时间:
2022-4-14 12:27
参考:
https://github.com/OpenNuvoton/N ... er/adc/src/libadc.c
在运行状态时(run-time, on the fly) 重新设置 ADC,可以先关掉再打开。
adc_close();
adc_open();
由于设置ADC的频率在函数 adc_init(),且这个函数不提供频率的入参,你需要自己改造一下。
adc_init()函数被adc_open()所调用
作者:
匿名
时间:
2022-4-14 13:51
谢谢你的及时回复。
我的代码跟你说的操作差不多,但不知道为什么切换就不成功呢。请问这跟用实时操作系统有没有关系呢?谢谢!
下面贴出我这边的代码,烦请你帮忙看一下,谢谢!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ADCDeinit(void) {
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~ADC_CON_ADC_EN);
outp32(REG_APBCLK, inp32(REG_APBCLK) & (~ADC_CKE));
outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & (~((0x03<<19) | (0x03<<16) | (0x5F<<24))));//UPLL 192/4/2 = 24MHz // ch_20220305
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ADCInit4Cal(void) {
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~ADC_CON_ADC_EN)); // ch_20220305
outp32(REG_APBCLK, inp32(REG_APBCLK) & (~ADC_CKE)); // ch_20220305
outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & (~((0x03<<19) | (0x03<<16) | (0x01<<24))));//UPLL 192/4/2 = 24MHz // ch_20220305
outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) | (0x03<<19) | (0x03<<16) | (0x5F<<24));//UPLL 192/4/2 = 24MHz // ch_20220228 : changed to 47 from 1.
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~( 0x03 << 14)));//normal mode
//outp32(REG_ADC_DLY, 0x150);
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ADCInit4Print(void) {
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~ADC_CON_ADC_EN)); // ch_20220305
outp32(REG_APBCLK, inp32(REG_APBCLK) & (~ADC_CKE)); // ch_20220305
outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) & (~((0x03<<19) | (0x03<<16) | (0x5F<<24))));//UPLL 192/4/2 = 24MHz // ch_20220305
outp32(REG_CLKDIV3, inp32(REG_CLKDIV3) | (0x03<<19) | (0x03<<16) | (0x02<<24));//UPLL 192/4/2 = 24MHz
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & (~( 0x03 << 14)));//normal mode
//outp32(REG_ADC_DLY, 0x150);
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);
}
切换前,我都会调用ADCDeinit()去关掉ADC模块。
作者:
arthur
时间:
2022-4-14 18:02
在 Deinit() 与 Init() 间加上 delay 试试看
作者:
匿名
时间:
2022-4-14 21:32
谢谢你的回复!
加了延时,
ADCDeinit(); // ch_20220413
sysprintf("AHBCLK = %x\tAPBCLK = %x\tADC_Clk = %x\n", inp32(REG_AHBCLK), inp32(REG_APBCLK), inp32(REG_CLKDIV3)); // ch_20220305
DelayTime(50000);
ADCInit(); // ch_20220305
sysprintf("AHBCLK = %x\tAPBCLK = %x\tADC_Clk = %x\n", inp32(REG_AHBCLK), inp32(REG_APBCLK), inp32(REG_CLKDIV3)); // ch_20220305
DelayTime(50000);
好像没有作用咯。
作者:
匿名
时间:
2022-4-14 21:40
这是切换前后寄存器的值。
作者:
匿名
时间:
2022-4-14 21:43
不知道怎么上传图片。
Create TASK for stack_32,768...
NutTask : name : task0001
Enter NutThreadCreate()...
task0001 task main idle
AHBCLK = 27011F APBCLK = 20083FD ADC_Clk = 5F1B0000
CalResult->SensorMode = 0 ->GapInten = 14 ->fPaperSize = 234 ->fGapSize = 23
AHBCLK = 27011F APBCLK = 20083FC ADC_Clk = 0
AHBCLK = 27011F APBCLK = 20083FD ADC_Clk = 21B0000
Exit TASK, runningThread->td_name : task0001
欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/)
Powered by Discuz! X3.2