错误一:高级定时器的MOE主输出使能
现象:电机没办法转动
猜测是电机驱动板出错导致,结果换了几块板重新测试发现没用,开始怀疑是软件配置问题。
解决方法:找来了别人配置高级定时器1的代码,逐行排查发现我没给定时器主输出时能MOE使能
TIM_CtrlPWMOutputs(TIM1,ENABLE);//MOE主输出 ②
错误二:端口重映射的使能
原因:查找原理图准备配置io口的时候
先找到控制马达的定时器
然后找到了对应定时器的io口
所以就直接配置了PE9 11 13 14四个io口
忘记了需要重映射
现象:同样是导致电机无法转动
解决方法:对照别人代码配置定时器发现没有重映射
打开AFIO时钟 使能完全重映射
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_AFIO , ENABLE);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE); // ①
void TIM1_PWM_Init(unsigned short arr,unsigned short psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3|RCC_APB1Periph_TIM4, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_AFIO , ENABLE);
//AFIO->MAPR|=3<<6;
GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE); // ①
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
// TIM1->BDTR|=1<<16;
TIM_CtrlPWMOutputs(TIM1,ENABLE);//MOE主输出 ②
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性di
TIM_OC1Init(TIM1,&TIM_OCInitStructure);//初始化CH1
TIM_OC2Init(TIM1,&TIM_OCInitStructure);//初始化CH2
TIM_OC3Init(TIM1,&TIM_OCInitStructure);//初始化CH3
TIM_OC4Init(TIM1,&TIM_OCInitStructure);//初始化CH4
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//CH1 预装载使能
TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);//CH2 预装载使能
TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);//CH3 预装载使能
TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);//CH4 预装载使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
//TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
这两个错误比较基础,由于入门时用的都是通用定时器,忽略了高级定时器的微小差别导致
错误二:灰度寻迹时候位运算错误导致
(影响最为严重,我就拿着这个错误的算法调试了一周多的车,发现还是会一直抖动)
以下第一句为错误代码
第二句为正确代码
错误一目了然
计算机的位运算应该是从0开始算,01234…
void CARgo_xunji()
{
/*DUc13-DUb9-DUb8-DUb5*/
// int bit1=(DUc13<<4)+(DUb9<<3)+(DUb8<<2)+DUb5;//一
int bit1=(DUc13<<3)+(DUb9<<2)+(DUb8<<1)+DUb5;//二
switch(bit1)
{
case 8:CARgo(L0,R0+13);break; //1000
case 12:CARgo(L0,R0+9);break; //1100
case 4:CARgo(L0,R0+6);break; //0100
case 2:CARgo(L0+6,R0);break; //0010
case 3:CARgo(L0+9,R0);break; //0011
case 1:CARgo(L0+13,R0);break; //0001
default: CARgo(L0,R0); break;
}
}
原因:写代码的时候想当然的认为第二个灰度应该是左移两位,实则第一位是0,第二位应该左移一位到1才对
现象:寻迹的时候一直左右抖动,不稳定,有时候从起始点出发的时候,会突然地向某个方向冲一下,然后开始寻迹,经过长时间的调试勉强能巡线,但是抖动很厉害,不稳定,后面迫不得已重新开始检查巡线
解决过程:
1.灰度传感器检测到黑线时会熄灭上面的红灯,测到白线会亮红灯,经过跟踪发现,当前面四个灰度读数为:1101(1为白0为黑)时,小车左转而非右转,经过反复测试发现从右往左数第二个灰度检测到黑线时,不是往左转,而是往右转,转的更偏了!
2.再经过对所有灰度排查,发现除了第一个灰度,其他三个灰度都是错误的!
3经过debug发现,没有1101这种情况,然后检查第二个灰度发现没问题.
4.经过学长的指点发现位运算错误,一切现象迎刃而解,第四个灰度不起到控制作用是因为第四位被挤到第五位了,第二位起到的作用相反,因为他被挤到第三位去了,所以他检测到黑线只会让小车走的更偏!其他灰度同理
错误四:无初始化延时函数
原因:
想写一个数线函数,用到了延时,我直接调用头文件就用了
后来发现动不了,
解决过程:经过学长帮我debug延时发现函数卡在延时函数,发现没初始化
最终学到了很重要的一个测试方法:debug函数
delay_init(); //!!!!!!③
错误五:if语句语法错误
原因:if else if else 的关系没搞清楚
现象:检测不到颜色数据
解决:刚开始以为是没收到数据,或者数据没接收到
所以那时候处境是这样的:
- 不知道串口是否接收到数据
- 其次不知道是不是串口接收数据的方式有问题
- 串口模块不知道有没有问题,怕是硬件问题
导致这些问题的原因就是没办法检验与测试,在开发板上测试的时候可以通过串口返回数据,但是这块板串口被拿来传输颜色数据了,
解决方法;
经过oled模块,成功显示出了数据,发现串口还是有接收到数据的,并且串口中断接受的数据也是我想要的
再结合debug排除以上三个问题,那么问题出在哪呢?
我发现oled总是显示color为0,然后发现语法错误,按照上图逻辑,程序每次都会跑到最后一个if和else,二并不是每个条件并列的关系
改正如下:
int tell_color(void)
{
if(rgb.Blue>rgb.Red&&rgb.Blue>rgb.Green&& 0x40<rgb.Blue && rgb.Blue<0x70)//lan
{ color=BLUE;
}
else if(rgb.Red>rgb.Blue&&rgb.Red>rgb.Green&&rgb.Red<0xd0)//lan
{color=RED;
}
else if(rgb.Green>rgb.Blue&&rgb.Green>rgb.Red&&rgb.Green<0x50&&rgb.Green>0x40)//lan
{ color=GREEN;
}
else if(rgb.Red>=0xE0&&rgb.Green>=0xD0&&rgb.Blue>=0XC0)//lan
{ color=WHITE;
}
else if(0x10<=rgb.Red&&rgb.Red<=0x30 && 0x20<=rgb.Green&&rgb.Green<=0X30 && 0x20<=rgb.Blue&&rgb.Blue<=0X3A)//lan
{ color=BLACK;
}
else color=0;
return color;
}