USB-CDC串口发送卡死,while循环正常,CDC设备在线,就是printf打印不出去
USB-CDC串口发送卡死,while循环正常,CDC设备在线,就是printf打印不出去//使用BL51链接器,BL51 misc取消警告代码:16,目标:内存模式使用large 模式,把变量存在Xdata中//使用USB库文件,并实现不断电下载。但是首次下载需要把P3.2拉低,在上电,USB库需要打开两个中断
//
#include "Config.h"
#define Vbus (*Vbus_ptr) //宏定义只是文本替换,没有顺序结构
#define Vfb (*Vfb_ptr)
#define Vre (*Vre_ptr)
PWMx_Duty PWMB_Duty;
volatile u8 ADC_tmp _at_ 0x0102;//每个通道占6位, 0|高字节 1|低 2|通道号 3|取平均值后余数 4|平均高字节 5|平均低字节(内存对齐在ADC设置)
u16 *Vbus_ptr = (u16 *)&ADC_tmp;//ADC通道0 的数值,定义了读取两个字节的指针
u16 *Vfb_ptr = (u16 *)&ADC_tmp;//ADC通道3 的数值,定义了读取两个字节的指针
u16 *Vre_ptr = (u16 *)&ADC_tmp;//ADC通道15 的数值,定义了读取两个字节的指针
/******************** IO配置函数 **************************/
void GPIO_config(void)
{
// ADC P1.3光耦反馈CH3
GPIO_InitTypeDef GPIO_InitStructure; // 结构定义
GPIO_InitStructure.Pin = GPIO_Pin_3; // 指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_HighZ; // 指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1, &GPIO_InitStructure); // 初始化
// ADC P1.0 Vus CH0
GPIO_InitStructure.Pin = GPIO_Pin_0; // 指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_HighZ; // 指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1, &GPIO_InitStructure); // 初始化
// PWM P1.7
GPIO_InitStructure.Pin = GPIO_Pin_7; // 指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_OUT_PP; // 指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1, &GPIO_InitStructure); // 初始化
// LED P5.4
GPIO_InitStructure.Pin = GPIO_Pin_4; // 指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_OUT_PP; // 指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P5, &GPIO_InitStructure); // 初始化
}
/******************* AD配置函数 *******************/
void ADC_config(void)//每次转换时间计算,
{
ADC_InitTypeDef ADC_InitStructure; // 结构定义
ADC_InitStructure.ADC_SMPduty = 31; // ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
ADC_InitStructure.ADC_CsSetup = 0; // ADC 通道选择时间控制 0(默认),1
ADC_InitStructure.ADC_CsHold = 1; // ADC 通道选择保持时间控制 0,1(默认),2,3
ADC_InitStructure.ADC_Speed = ADC_SPEED_2X5T; // 设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16T
ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; // ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
ADC_Inilize(&ADC_InitStructure); // 初始化
ADC_PowerControl(ENABLE); // ADC电源开关, ENABLE或DISABLE
NVIC_ADC_Init(ENABLE, Priority_0); // 中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
void ADC_DMA(void) // 后续需要创建文件和结构体
{
DMA_ADC_CFG = 0; // 不允许中断
DMA_ADC_RXAH = (unsigned int)&ADC_tmp >> 8;
DMA_ADC_RXAL = (unsigned int)&ADC_tmp; // ADC数据存放的地址
DMA_ADC_CFG2 = 0x00; // 每个通道转换次数转换1次
DMA_ADC_CHSW0 = 0x09; // 通道使能 0-7
DMA_ADC_CHSW1 = 0x80; // 通道使能 8-15
DMA_ADC_CR = 0xff; // 允许DMA 开启DMA
}
/***************PWM初始化函数 *****************/
void PWM_config(void)
{
PWMx_InitDefine PWMx_InitStructure;
PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; // 模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
PWMx_InitStructure.PWM_Duty = PWMB_Duty.PWM5_Duty; // PWM占空比时间, 0~Period
PWMx_InitStructure.PWM_EnoSelect = ENO5P; // 输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
PWM_Configuration(PWM5, &PWMx_InitStructure); // 初始化PWM,PWMA,PWMB
PWMx_InitStructure.PWM_Period = 692; // 周期时间, 0~65535
PWMx_InitStructure.PWM_DeadTime = 0; // 死区发生器设置, 0~255
PWMx_InitStructure.PWM_MainOutEnable = ENABLE; // 主输出使能, ENABLE,DISABLE
PWMx_InitStructure.PWM_CEN_Enable = ENABLE; // 使能计数器, ENABLE,DISABLE
PWM_Configuration(PWMB, &PWMx_InitStructure);// 初始化PWM通用寄存器,PWMA,PWMB
// NVIC_PWM_Init(PWMB,DISABLE,Priority_0);
PWM5_SW(PWM5_SW_P17); // PWM5_SW_P20,PWM5_SW_P17,PWM5_SW_P00,PWM5_SW_P74
PWMB_Duty.PWM5_Duty = 0;
}
/************************ 定时器配置 ****************************/
void Timer_config(void)
{
TIM_InitTypeDef TIM_InitStructure; // 结构定义
// 定时器0做16位自动重装, 中断频率为100000HZ,中断函数从P6.7取反输出50KHZ方波信号.
TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; // 指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T;// 指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
TIM_InitStructure.TIM_ClkOut = DISABLE; // 是否输出高速脉冲, ENABLE或DISABLE
TIM_InitStructure.TIM_Value = 0; // 65535-(MAIN_Fosc/65000); //初值,
TIM_InitStructure.TIM_Run = ENABLE; // 是否初始化后启动定时器, ENABLE或DISABLE
Timer_Inilize(Timer0, &TIM_InitStructure); // 初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
NVIC_Timer0_Init(ENABLE, Priority_0); // 中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
void main(void)
{
uint32_t step1;
uint32_t step2;
u16 Vbus_Actual;
u16 Vfb_Actual;
u8 i;
EAXSFR(); /* 扩展寄存器访问使能 */
GPIO_config();
ADC_config();
PWM_config();
Timer_config();
ADC_DMA();
usb_init(); // USB CDC 接口配置
IE2 |= 0x80; // 使能USB中断
EA = 1; // IE |= 0X80;
while (DeviceState != DEVSTATE_CONFIGURED)
; // 等待USB完成配置
while (1)
{
step1 = (uint32_t)Vfb * 1190;// 4095 * 1190 = 4,874,550
step2 = step1 / Vre; // 4,874,550 / 1151 ≈ 4239.57
printf("反馈电压是:%hu\n\n",Vbus);
DMA_ADC_CR |= 0x40; // ADC_DMA继续开始
delay_ms(1000);
P54 = ~P54;
}
}
现象描述,while循环中LED继续闪烁,但是USB_CDC的串口,在接收了一段时间后卡死不动了,不停电下载会一直提示“HID-ISP...”
我的初步判断是,USB这边配置没正确,但是不知道问题根本原因,
可以复现吗,上传完整工程我晚点试下 ercircle 发表于 2025-5-24 14:28
可以复现吗,上传完整工程我晚点试下
IRC=45.158MHZ
复位口做I/O口
大龄剩男 发表于 2025-5-24 23:35
IRC=45.158MHZ
复位口做I/O口
STC8H8K64U, 先将主频降到 40MHz, 再测试下 确实复测用40MHz正常,45.1584MHz复现阻塞异常
另外这个delay_ms入参是unsigned char ms,不要输入1000.
ercircle 发表于 2025-5-25 14:19
确实复测用40MHz正常,45.1584MHz复现阻塞异常
另外这个delay_ms入参是unsigned char ms,不要输入1000.
多谢支持,把主频降到40Mhz,不会卡了
页:
[1]