言之者无罪,闻之者足以戒。 - “诗序”
在上一篇文章中,PWM的调速我们已经实现了 ,今天主要实现的是数据的扫描和存储。其实也是比较简单的但是自己第一次写15 的代码,也是第一次接触到矩阵寻迹,所以进度比较慢,还在这里啰啰嗦嗦的写出来,可能在有些人眼里这些很简单,但是对于初次接触的人来说,还是有一点小麻烦的,希望的我这些文字能够对初学的你以及我自己有些帮助。
我第一次写的扫描函数是一次扫描五行存储在一个二维数组当中但是我发现这样存储的想法挺好但是自己实现不了,而且在第一的PWM控速的时候,我把PWM的初始化配置和调速的控制都写在了一个函数中了(就是我上一篇文章的那中写法),这样我在每次调用PWM函数实现控速的时候都会初始化一次,这样就导致了我不能完全的实现控速了。后来我对程序进行了修改:
/*速度控制子函数*/
void PWM_Control(int set_PWM1,int set_PWM2)
{
CL = 0X00; //复位PCA寄存器
CH = 0X00;
CCAP0H = CCAP0L = set_PWM1;
CCAP1H = CCAP1L = set_PWM2;
CL = 0X00; //复位PCA寄存器
CH = 0X00;
// CCAP0H = 0X08;//右轮
// CCAP0L = 0X08;
// CCAP1H = 0x09;//左轮
// CCAP1L = 0x09;
}
/*PWM控速初始化函数*/
void PWM_Init()
{
AUXR1 &= 0XCF;
CCON = 0X00; //初始化PCA控制寄存器,PCA定时器停止,清除CF标志,清除模块中断标志
CL = 0X00; //复位PCA寄存器
CH = 0X00;
CMOD = 0X02; //设置PCA时钟(系统时钟/2),禁止PCA计数器中断
CCAPM0 = 0x42; //PCA模块0为8位PWM模式
CCAPM1 = 0x42; //PCA模块0为8位PWM模式
PCA_PWM1 = 0x00; //PCA模块0工作于8位PWM
PCA_PWM0 = 0x00; //PCA模块0工作于8位PWM
CR = 1; //PCA定时器开始工作
}
我写成这种形式就OK了,这样你只需要在主函数中调用一次PWM初始化函数,在要控速的地方调用调速函数就能实现PWM控速了。
下面接着说,我的数据读取的存储问题,因为第一天晚上把数据存储在二维数组中的时候我失败了,所以第二天上课的时候我就想了一个最基础、最简单、当然也是最笨的方法,就是我一行一行的存储,存储在一维的数组中,反正总共就五行,我只需要定义五个一维数组就可以解决问题了,就这样我解决了数据的读取和存储的问题。
下面看一下我写的PWM控速和数据的读取和存储的程序:
#include <STC15F2K60S2.H>
#define FOSC 11059200L//定义主时钟
/*电机控制位*/
sbit L_M_E = P1^0;
sbit L_M_1 = P1^2;
sbit L_M_2 = P1^3;
sbit R_M_E = P1^1;
sbit R_M_1 = P1^4;
sbit R_M_2 = P1^5;
/*寻迹相关控制位*/
#define TraceMatrix_DB P0
sbit TraceMatrix_row1 = P2^4;
sbit TraceMatrix_row2 = P2^3;
sbit TraceMatrix_row3 = P2^2;
sbit TraceMatrix_row4 = P2^1;
sbit TraceMatrix_row5 = P2^0;
typedef unsigned int u16;
typedef unsigned char u8;
u16 Row_Col_1[7] = {0};
u16 Row_Col_2[7] = {0};
u16 Row_Col_3[7] = {0};
u16 Row_Col_4[7] = {0};
u16 Row_Col_5[7] = {0};
u16 Read_time=0;
u8 Lettic_Flag_row = 0;
/*速度控制子函数*/
void PWM_Control(int set_PWM1,int set_PWM2)
{
CL = 0X00; //复位PCA寄存器
CH = 0X00;
CCAP0H = CCAP0L = set_PWM1;
CCAP1H = CCAP1L = set_PWM2;
CL = 0X00; //复位PCA寄存器
CH = 0X00;
// CCAP0H = 0X08;//右轮
// CCAP0L = 0X08;
// CCAP1H = 0x09;//左轮
// CCAP1L = 0x09;
}
/*PWM控速初始化函数*/
void PWM_Init()
{
AUXR1 &= 0XCF;
CCON = 0X00; //初始化PCA控制寄存器,PCA定时器停止,清除CF标志,清除模块中断标志
CL = 0X00; //复位PCA寄存器
CH = 0X00;
CMOD = 0X02; //设置PCA时钟(系统时钟/2),禁止PCA计数器中断
CCAPM0 = 0x42; //PCA模块0为8位PWM模式
CCAPM1 = 0x42; //PCA模块0为8位PWM模式
PCA_PWM1 = 0x00; //PCA模块0工作于8位PWM
PCA_PWM0 = 0x00; //PCA模块0工作于8位PWM
CR = 1; //PCA定时器开始工作
}
/*直行函数*/
void Forward()
{
L_M_1 = 1;
L_M_2 = 0;
R_M_1 = 1;
R_M_2 = 0;
}
/*停止函数*/
void Stop()
{
L_M_1 = 0;
L_M_2 = 0;
R_M_1 = 0;
R_M_2 = 0;
}
/*小车状态控制函数*/
void Lettice()
{
if((Row_Col_1[3] == 1) && (Row_Col_2[3] == 1) && (Row_Col_3[3] == 1) && (Row_Col_4[3] == 1) && (Row_Col_5[3] == 1))
{
PWM_Control(0X10,0X10);
Forward();
}
else if((Row_Col_1[0] == 1) && (Row_Col_2[0] == 1) && (Row_Col_3[0] == 1) && (Row_Col_4[0] == 1) && (Row_Col_5[0] == 1))
{
Stop();
PWM_Control(0X80,0X90);
}
else
{
PWM_Control(0X20,0X20);
Forward();
}
}
/*矩阵状态读取*/
void Read_TraceMatrix_IO()
{
u8 X=0;
u8 Read_col;
if(Lettic_Flag_row == 1)
{
Lettic_Flag_row = 0;
/*********************************第一行数据的读取**************************************/
TraceMatrix_row1 = 0;
//读取P0口的数据
X=P0;
Read_col=X&0x7f;
//判断是第几列的灯寻到黑线
if(Read_col == 0x01)
{
Row_Col_1[0]=1;
}
if(Read_col == 0x02)
{
Row_Col_1[1]=1;
}
if(Read_col == 0x04)
{
Row_Col_1[2]=1;
}
if(Read_col == 0x08)
{
Row_Col_1[3]=1;
}
if(Read_col == 0x10)
{
Row_Col_1[4]=1;
}
if(Read_col == 0x20)
{
Row_Col_1[5]=1;
}
if(Read_col == 0x40)
{
Row_Col_1[6]=1;
}
TraceMatrix_row1 = 1;
/**********************************第二行数据的读取*********************************/
TraceMatrix_row2 = 0;
X = 0;
//读取P0口的数据
X=P0;
Read_col=X&0x7f;
//判断是第几列的灯寻到黑线
if(Read_col == 0x01)
{
Row_Col_2[0]=1;
}
if(Read_col == 0x02)
{
Row_Col_2[1]=1;
}
if(Read_col == 0x04)
{
Row_Col_2[2]=1;
}
if(Read_col == 0x08)
{
Row_Col_2[3]=1;
}
if(Read_col == 0x10)
{
Row_Col_2[4]=1;
}
if(Read_col == 0x20)
{
Row_Col_2[5]=1;
}
if(Read_col == 0x40)
{
Row_Col_2[6]=1;
}
TraceMatrix_row2 = 1;
/************************************第三行数据的读取**********************************/
TraceMatrix_row3 = 0;
X = 0;
//读取P0口的数据
X=P0;
Read_col=X&0x7f;
//判断是第几列的灯寻到黑线
if(Read_col == 0x01)
{
Row_Col_3[0]=1;
}
if(Read_col == 0x02)
{
Row_Col_3[1]=1;
}
if(Read_col == 0x04)
{
Row_Col_3[2]=1;
}
if(Read_col == 0x08)
{
Row_Col_3[3]=1;
}
if(Read_col == 0x10)
{
Row_Col_3[4]=1;
}
if(Read_col == 0x20)
{
Row_Col_3[5]=1;
}
if(Read_col == 0x40)
{
Row_Col_3[6]=1;
}
TraceMatrix_row3 = 1;
/************************************第四行数据的读取**********************************/
TraceMatrix_row4 = 0;
X = 0;
//读取P0口的数据
X=P0;
Read_col=X&0x7f;
//判断是第几列的灯寻到黑线
if(Read_col == 0x01)
{
Row_Col_4[0]=1;
}
if(Read_col == 0x02)
{
Row_Col_4[1]=1;
}
if(Read_col == 0x04)
{
Row_Col_4[2]=1;
}
if(Read_col == 0x08)
{
Row_Col_4[3]=1;
}
if(Read_col == 0x10)
{
Row_Col_4[4]=1;
}
if(Read_col == 0x20)
{
Row_Col_4[5]=1;
}
if(Read_col == 0x40)
{
Row_Col_4[6]=1;
}
TraceMatrix_row4 = 1;
/************************************第五行数据的读取**********************************/
TraceMatrix_row5 = 0;
X = 0;
//读取P0口的数据
X=P0;
Read_col=X&0x7f;
//判断是第几列的灯寻到黑线
if(Read_col == 0x01)
{
Row_Col_5[0]=1;
}
if(Read_col == 0x02)
{
Row_Col_5[1]=1;
}
if(Read_col == 0x04)
{
Row_Col_5[2]=1;
}
if(Read_col == 0x08)
{
Row_Col_5[3]=1;
}
if(Read_col == 0x10)
{
Row_Col_5[4]=1;
}
if(Read_col == 0x20)
{
Row_Col_5[5]=1;
}
if(Read_col == 0x40)
{
Row_Col_5[6]=1;
}
TraceMatrix_row5 = 1;
}
}
/*定时器0初始化函数*/
void Timer0Init()
{
TH0=0xFF;//定时0.1ms
TL0=0x9C;
TMOD=0X01;//定时器0的工作方式是方式1
EA=1;
ET0=1;
TR0=1;
}
/*定时器0的中断函数*/
void Timer0_isr() interrupt 1 using 1
{
TH0=0xFF;//定时0.1ms
TL0=0x9C;
Read_time++;
if(Read_time == 5)
{
Read_time = 0;
Row_Col_1[0] = 0;
Row_Col_1[1] = 0;
Row_Col_1[2] = 0;
Row_Col_1[3] = 0;
Row_Col_1[4] = 0;
Row_Col_1[5] = 0;
Row_Col_1[6] = 0;
Row_Col_2[0] = 0;
Row_Col_2[1] = 0;
Row_Col_2[2] = 0;
Row_Col_2[3] = 0;
Row_Col_2[4] = 0;
Row_Col_2[5] = 0;
Row_Col_2[6] = 0;
Row_Col_3[0] = 0;
Row_Col_3[1] = 0;
Row_Col_3[2] = 0;
Row_Col_3[3] = 0;
Row_Col_3[4] = 0;
Row_Col_3[5] = 0;
Row_Col_3[6] = 0;
Row_Col_4[0] = 0;
Row_Col_4[1] = 0;
Row_Col_4[2] = 0;
Row_Col_4[3] = 0;
Row_Col_4[4] = 0;
Row_Col_4[5] = 0;
Row_Col_4[6] = 0;
Row_Col_5[0] = 0;
Row_Col_5[1] = 0;
Row_Col_5[2] = 0;
Row_Col_5[3] = 0;
Row_Col_5[4] = 0;
Row_Col_5[5] = 0;
Row_Col_5[6] = 0;
Read_TraceMatrix_IO();
Lettic_Flag_row = 1;
}
}
void main()
{
PWM_Init();
Timer0Init();
while(1)
{
Lettice();
}
}
其实我上面 所做的工作都是最简单的工作,真正不好解决的是数据的处理的问题,因为用的是5X7的矩阵,而对于我而言有是的第一次接触所以对于数据的处理还是有一定的难度的。现在我的最基本的思想是尽可能的包括所有的情况,以最笨的方法实现矩阵寻迹。