首先,我选择的是B题————自动循迹小车,具体如下:

B题:自动循迹小车
1.任务
设计制作一个自动循迹小车。小车采用一片 TI公司LDC1314或LDC1000电感数字转换器作为循迹传感器,在规定的平面跑道自动按顺时针方向循迹前进。跑道的标识为一根直径0.6~0.9mm的细铁丝,按照图1的示意尺寸,用透明胶带将其贴在跑道上。图中所有圆弧的半径均为为20cm±2cm。

图1 跑道示意图
2.要求
(1)在图1小车所在的直线区任意指定一起点(终点),小车依据跑道上设置的铁丝标识,自动绕跑道跑完一圈。时间不得超过10分钟。小车运行时必须保持轨迹铁丝位于小车垂直投影之下。如有越出,每次扣2分。 (40分)
(2)实时显示小车行驶的距离和运行时间。 (10分)
(3)在任意直线段铁丝上放置4个直径约19mm的镀镍钢芯硬币(第五套人民币的1角硬币),硬币边缘紧贴铁丝,如图1所示。小车路过硬币时能够发现并发出声音提示。 (20分)
(4)尽量减少小车绕跑道跑完一圈运行时间。 (25分)
(5)其他。 ( 5分)
(6)设计报告 (20分)
项 目 主要内容 满分
方案论证 比较与选择,方案描述 3
理论分析与计算 系统相关参数设计 5
电路与程序设计 系统组成,原理框图与各部分的电路图,系统软件与流程图 5
测试方案与测试结果 测试结果完整性,测试结果分析 5
设计报告结构及规范性 摘要,正文结构规范,图表的完整与准确性 2
总 分 20

3.说明
(1)自动循迹小车允许用玩具车改装。小车用自带电池供电运行,不能使用外接电源。小车的尺寸为其在地面的投影不超过A4纸大小。小车自动运行后,不得有任何人工干预小车运动的行为,如遥控等。
(2)电感传感器除了使用TI公司配发的LDC1314芯片外,也可使用LDC1000芯片或模块,数量也仅限一只。不得使用任何其他类型的传感器用于循迹。
(3)跑道除指定的铁丝外,不得另外增加任何标记。跑道附近不应有其他额外金属物体。

直入主题:大家都知道比赛要用到的主要器件会提前通知,梁比赛之前搭好了小车并且调试好了LDC1000。然题目出来之后,我们决定采用ldc1314(因为只能用一块探测芯片,事后才发现这是一个多么错误的决定)至于小车本身我就不过多涉及,很普通的一个小车。几个重要模块:
一:电源模块
二:核心板
三:金属轨道探测模块(ldc1000或者ldc1314)
正如前面所言,比赛开始后我们放弃了调好的ldc1000改用了ldc1314,好在有ldc1000的经验,第一天我们小组做出了ldc1000的模块,也写好了相应的驱动代码。然后就开始调试小车寻迹,用了PID算法,按照P,D,I的顺序调的。途中由于用的开关电源而没有加保险管,在熬夜过程中不小心把电源接反了而烧了2576开关电源芯片(也不知道加了保险管是否真的就保险,但是后面加了保险管再也没烧过了,毕竟比赛,最好不要节外生枝)就这样在第三天早上我们调好了PID,小车能勉强走完全程完成寻迹了,心里那个激动啊,就这样我们继续修改PID参数,力求更好的效果。但第四天早上起来,不知道怎么回事把LDC1314烧了,不明不白的也不知道哪里出问题了。最悲哀就是学校老师不再给我们LDC1314。失望之后,我拿出了LDC1000,还是用ldc1000,一开始不用ldc1000是因为它只有一个通道——只能接一个线圈,而LDC1314有四个通道——能接四个线圈,所以LDC1314在寻迹上被我们理所当然的认为更好了,然而时候经过查阅datasheet和实际验证以及比赛群里的同学反映,LDC1314检测距离和灵敏度明显小于LDC1000。正式因为如此ldc’1000也是很多成功者的选择,因为ldc’1314实在是太短了,稍微数据丢失(它没有检测到)车就很容易出轨道了。从第四天开始,我们改用LDC1000——方案有二:
一:用一个线圈,利用PID来判断方向的转变(认识的一位非本校的师兄就是这样实现的),不过难点在于1,线圈要大一点,感应强度要强一些,2,小车要好控制(电机和舵机要好用)3,PID算法参数要选的非常好才行,不然很容易出轨道。
二:用两个线圈,安置在左和右用来判断方向,加上PID更可以精确一些控制。
由于我们用了直流电机(并没编码电机),其次舵机不怎么样,而且我没有好的大一点的线圈(学校老师打的PCB线圈效果极差!),担心一个线圈调不出来,所以我们采用两个线圈切换办法同样切换装置也是问题(一:用什么切换,二:切换频率对效果的影响)方案同样有二:1场管,2继电器。最终选择了继电器,频率改变小一些(的确·继电器对线圈采集的数据有一定影响,而且电流有一点变化),好在最终也算实现了。

总结几点:
一:熬夜一定要放慢动作,谨慎做事,很容易因为太困弄坏东西,得不偿失(比赛七天,前五天每天4点睡,八点起,后两天连续通宵)在很累很困的情况很容易弄错的,我们烧了1314和电源板很大原因就是太累太困又心急。
二:继电器驱动使用灌电流,不能使用拉电流(一开始怎么都驱动不了继电器,就连2003都不行,也是想不通,后来查资料找到了,卡了半天时间)
三:PID参数一定对应一个系统,系统变则参数变
四:使用SPI3的同时不能使用JTAG的复用时钟,需要关闭其复用时钟(具体我再研究研究,比赛当时使用SPI3一开始不顺利,关闭JTAG的复用时钟就ok了)
五:LDC1314和LDC1000的芯片可以改变检测的数值范围,调大差距值,但是我认为并不能改变灵敏度,而是通过调节线圈电感和连接的电容来改变灵敏度(具体可以见TI官网的在线计算工具)

最后就是一点遗憾了:第一:觉得自己准备不足,很多东西应该自己准备好的,尤其是小车,我很后悔用了一个性能太差的,直流电机(两边轮子相同电压转速还明显不一样),舵机小角度比较差,要么不转,要么转大角度。其他就是线圈我很后悔没有自己打,学校打那个确实太差,有些根本就检测不大。第二:后悔放弃LDC1000,应为LDC1314确实检测距离在我那个硬件条件太短,几乎擦着地面走,LDC1000则还要好些,几乎是两倍的距离吧,说实话一开始以为TI推销他的新出的1314就很在意这个。事实证明在硬件不太好的情况下,LDC1000还好弄一点·。第三:熬夜不要急,血的教训。

下面给出部分代码:

include

include “usart.h”

include “ldc1000.h”

include “1602.h”

include “beep.h”

include “delay.h”

include “motor.h”

include “pwm_tim5.h”

include “step_motor.h”

include “ldc_intruput.h”

include “pid.h”

extern unsigned long ProximityData; //LDC上Proximity Data
extern unsigned char flag;
extern u16 CCR3_Val , CCR4_Val ;//后轮2,3 舵机0

unsigned long red_ProximityData, bule_ProximityData;

void display(unsigned long temp,u16 adr);
void jichu_ProximityData(void);

unsigned long jichu_red,jichu_bule;
u16 time,distance;

uint8_t table[10]=”0123456789”;
uint8_t table1[10]=”Time:”;
uint8_t table2[10]=”distance:”;
extern u16 CCR3_Val;
u8 i;

int main (void)
{
NVIC_Configuration();
delay_init();
USART1_Config();
inct();
beep_Init();
SPI_LDC_Init();
TIM5_PWM_Init();
TIM7_ldc_Init(60000-1,72-1);
MOTOR_Init();
jidainqi_Init();

write_com(0x80);
delay(10);
for(i=0;i<6;i++)
write_data(table1[i]);
write_com(0x80+0x0a);
write_data('s');
write_com(0x80+0x40);

for(i=0;i<9;i++)
write_data(table2[i]);
write_com(0x80+0x4e);
write_data(‘c’);
write_com(0x80+0x4f);
write_data(‘m’);

jichu_ProximityData();
Rear_wheel_direction(0);
while(1)
{if(jidianqi==0)              {LDCRead();if(ProximityData>9000&ProximityData<14000){red_ProximityData=ProximityData;display(red_ProximityData,0x80+0x49);}else if(ProximityData<9000&ProximityData>8000){beep=1;delay_ms(100);beep=0;}else if(ProximityData<8000){bule_ProximityData=ProximityData;

// display(bule_ProximityData,0x80+0x4F);
}
else if(ProximityData>=16000) //硬币
{
beep=1;
delay_ms(100);
beep=0;
}
delay_ms(50);
jidianqi=1;
}
else if(jidianqi==1)
{
LDCRead();
if(ProximityData>9000&ProximityData<14000)
{
red_ProximityData=ProximityData;
// display(red_ProximityData,0x80+0x49);
}
// else if(ProximityData<9000&ProximityData>8000)
// {
// beep=1;
// delay_ms(100);
// beep=0;
// }
else if(ProximityData<8000)
{
bule_ProximityData=ProximityData;
// display(bule_ProximityData,0x80+0x4F);
}
else if(ProximityData>16000) //硬币
{
beep=1;
delay_ms(100);
beep=0;
}
delay_ms(50);
jidianqi=0;
}

}
}
void display(unsigned long temp,u16 adr)
{
uint8_t i;
write_com(0x04);
delay(30);
write_com(adr);
while(temp)
{
i=temp%10;
write_data(table[i]);
temp/=10;
}
write_com(0x06);
}
void jichu_ProximityData() //获取基础值
{
u8 j;
for(j=0;j<10;j++)
{
if(jidianqi==0)
{
LDCRead();
if(ProximityData>9000&&ProximityData<18000)
{
red_ProximityData=ProximityData;
// display(red_ProximityData,0x80+0x49);
}
else if(ProximityData<9000)
{
bule_ProximityData=ProximityData;
// display(bule_ProximityData,0x80+0x4F);
}
else if(ProximityData>=18000) //硬币
{
beep=1;
delay_ms(100);
beep=0;
}
jidianqi=1;
delay_ms(100);
}
else if(jidianqi==1)
{
LDCRead();
if(ProximityData>9000&&ProximityData<18000)
{
red_ProximityData=ProximityData;
// display(red_ProximityData,0x80+0x49);
}
else if(ProximityData<9000)
{
bule_ProximityData=ProximityData;
// display(bule_ProximityData,0x80+0x4F);
}
else if(ProximityData>=18000) //硬币
{
beep=1;
delay_ms(100);
beep=0;
}
jidianqi=0;
delay_ms(100);
}
}
jichu_red=red_ProximityData;
jichu_bule=bule_ProximityData;
}

LDC1000驱动

ifndef LDC24L01_H

define LDC24L01_H

include

define GPIO_LDC GPIOC

define GPIO_LDC_CSN_Pin GPIO_Pin_5

define GPIO_LDC_CE_Pin GPIO_Pin_2

define GPIO_LDC_IQ_Pin GPIO_Pin_4

define SPI_NOP 0XFF//空指令用来读状态寄存器

/******寄存器地址区*********/

define LDC1000_CMD_REVID 0x00

define LDC1000_CMD_RPMAX 0x01

define LDC1000_CMD_RPMIN 0x02

define LDC1000_CMD_SENSORFREQ 0x03

define LDC1000_CMD_LDCCONFIG 0x04

define LDC1000_CMD_CLKCONFIG 0x05

define LDC1000_CMD_THRESHILSB 0x06

define LDC1000_CMD_THRESHIMSB 0x07

define LDC1000_CMD_THRESLOLSB 0x08

define LDC1000_CMD_THRESLOMSB 0x09

define LDC1000_CMD_INTCONFIG 0x0A

define LDC1000_CMD_PWRCONFIG 0x0B

define LDC1000_CMD_STATUS 0x20

define LDC1000_CMD_PROXLSB 0x21

define LDC1000_CMD_PROXMSB 0x22

define LDC1000_CMD_FREQCTRLSB 0x23

define LDC1000_CMD_FREQCTRMID 0x24

define LDC1000_CMD_FREQCTRMSB 0x25

// LDC BITMASKS

define LDC1000_BIT_AMPLITUDE 0x18

define LDC1000_BIT_RESPTIME 0x07

define LDC1000_BIT_CLKSEL 0x02

define LDC1000_BIT_CLKPD 0x01

define LDC1000_BIT_INTMODE 0x07

define LDC1000_BIT_PWRMODE 0x01

define LDC1000_BIT_STATUSOSC 0x80

define LDC1000_BIT_STATUSDRDYB 0x40

define LDC1000_BIT_STATUSWAKEUP 0x20

define LDC1000_BIT_STATUSCOMP 0x10

define TEST_RPMAX_MAX 0x13 /*< maximum calibration value for RPMAX /

define TEST_RPMAX_MIN 0x10 /*< minimum calibration value for RPMAX /

define TEST_RPMAX_INIT TEST_RPMAX_MIN+1 /*< RPMAX initial value /

define TEST_RPMIN_MAX 0x3D /*< maximum calibration value for RPMIN /

define TEST_RPMIN_MIN 0x3A /*< minimum calibration value for RPMIN /

define TEST_RPMIN_INIT TEST_RPMIN_MIN+1 /*< RPMIN initial value /

// Final Test Range

define TEST_RP_MSB_MAX 0x12 /*< maximum value for proximity data /

define TEST_RP_MSB_MIN 0x0A /*< minimum value for proximity data /

define TEST_FC_MAX 0x0D5D /*< maximum value for frequency counter /

define TEST_FC_MIN 0x0D39 /*< minimum value for frequency counter /

/******宏定义区*********/

define LDC_CSN_HIGH() GPIO_SetBits(GPIO_LDC, GPIO_LDC_CSN_Pin)

define LDC_CSN_LOW() GPIO_ResetBits(GPIO_LDC, GPIO_LDC_CSN_Pin) //csn置低

define LDC_Read_IRQ() GPIO_ReadInputDataBit (GPIO_LDC, GPIO_LDC_IQ_Pin)

/******函数声明区*********/
extern void SPI_LDC_Init(void);//spi的初始化
u8 SPI_LDC_RW(u8 data);
static void SPI_LDC_WriteReg(u8 reg,u8 data);//向reg寄存器中写入data
static u8 SPI_LDC_ReadReg(u8 reg);//读取指定状态寄存器的值
void LDC1000_init(void);
void LDCRead(void);
extern void MY_SPI_Init(void);
void TIM3_NVIC_Configuration(void);
static void TIM3_GPIO_Config(void);
static void TIM3_Mode_Config(void);
void TIM3_Init(void);
float CountRp(void);
unsigned long Fsensor(unsigned long lFcount);
unsigned long Fsensor(unsigned long lFcount);
unsigned long CountInductor(unsigned long lFsensor);

endif

include “ldc1000.h”

include “usart.h”

include “math.h”

define SPI_RWBIT 0x80

define Fext 32768 //32768 Hz

define ResponseTime 6144

define CapVal 0.0001 //1uF*/

unsigned long ProximityData;
unsigned long FrequencyData;
unsigned char flag;
volatile u32 speed=999;

__IO uint16_t DataRcv[5] ;

/*************初始化spi***********************
*功 能: 初始化野火的spi
*形 参: void
*返 回 值:void
*备 注:
*******************************************************/
extern void MY_SPI_Init(void)
{
SPI_InitTypeDef SPI_InitStr;
GPIO_InitTypeDef GPIO_InitStr;

/*使能GPIOB,GPIOD,复用功能时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);/*使能SPI1时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);/*对硬件stm32的SPI配置*/
/*配置 SPI_LDC_SPI的 SCK,MISO,MOSI引脚,GPIOA^5,GPIOA^6,GPIOA^7 */
GPIO_InitStr.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStr.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStr.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能
GPIO_Init(GPIOA, &GPIO_InitStr);/*对从机LDC24L01的控制角配置*/
/*配置CE引脚,GPIOA^2和 CSB 引脚*/
GPIO_InitStr.GPIO_Pin = GPIO_LDC_CSN_Pin;
GPIO_InitStr.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStr.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStr);/*对硬件stm32的SPI配置*/
/*配置SPI_LDC_SPI的IRQ引脚,GPIOA^3*/
GPIO_InitStr.GPIO_Pin = GPIO_LDC_IQ_Pin;
GPIO_InitStr.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStr.GPIO_Mode = GPIO_Mode_IPU ;  //上拉输入
GPIO_Init(GPIOC, &GPIO_InitStr);/* 这是自定义的宏,用于拉高csn引脚,LDC进入空闲状态 */
LDC_CSN_HIGH();SPI_InitStr.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线全双工
SPI_InitStr.SPI_Mode = SPI_Mode_Master;                     //主模式
SPI_InitStr.SPI_DataSize = SPI_DataSize_8b;                 //数据大小8位
SPI_InitStr.SPI_CPOL = SPI_CPOL_High;                       //时钟极性,空闲时为低
SPI_InitStr.SPI_CPHA = SPI_CPHA_2Edge;                      //第1个边沿有效,上升沿为采样时刻
SPI_InitStr.SPI_NSS = SPI_NSS_Soft;                         //NSS信号由软件产生
SPI_InitStr.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  //8分频,9MHz
SPI_InitStr.SPI_FirstBit = SPI_FirstBit_MSB;                //高位在前
SPI_InitStr.SPI_CRCPolynomial = 7;                          //CRC校验复位
SPI_Init(SPI1, &SPI_InitStr);/* Enable SPI1  */
SPI_Cmd(SPI1, ENABLE);

}

/*************向LDC中读/写一个字节*************
*功 能: 向LDC中读/写一个字节
*形 参: 写入的数据
*返 回 值: 读取得的数据
*备 注:
*******************************************************/
u8 SPI_LDC_RW(u8 data) //向LDC中读写一个字节
{
/* 当 SPI发送缓冲器非空时等待 */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

/* 通过 SPI2发送一字节数据 */
SPI_I2S_SendData(SPI1, data);/* 当SPI接收缓冲器为空时等待 */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);

}

/*************向LDC指定的寄存器写值*************
*功 能: 向LDC指定的寄存器写值
*形 参: reg:LDC的命令+寄存器地址。
* data:将要向寄存器写入的数据
*返 回 值: 寄存器的状态
*备 注:
*******************************************************/
static void SPI_LDC_WriteReg(u8 reg,u8 data)
{

// LDC_CE_LOW();//进入待机模式1,低功耗模式,此模式下LDC可以接收数据
LDC_CSN_LOW();//拉低csn片选信号,使能LDC的spi传输

SPI_LDC_RW(reg);//向LDC发送命令和寄存器的号SPI_LDC_RW(data);//向刚才指定的寄存器写入数据LDC_CSN_HIGH();//拉高csn片选信号,即释放LDC的spi传输完毕;

}

/*************读取LDC指定的寄存器值*************
*功 能: 读取LDC指定的寄存器值
*形 参: reg:LDC寄存器地址。
*返 回 值: 状态寄存器的数据
*备 注:
*******************************************************/
static u8 SPI_LDC_ReadReg(u8 reg)
{
u8 Reg_Value;

// LDC_CE_LOW();//进入待机模式1,低功耗模式,此模式下LDC可以接收数据
LDC_CSN_LOW();//拉低csn片选信号,使能LDC的spi传输

SPI_LDC_RW(reg|SPI_RWBIT);//选择寄存器
Reg_Value = SPI_LDC_RW(SPI_NOP);LDC_CSN_HIGH();//拉高csn片选信号,即释放LDC的spi传输完毕;return Reg_Value;

}

/**********************************************************
* @brief: LDC1000初始化配置,ps:在SPI中配置了数据位16个数据长度,故
* 在发送数据时可以将地址和值进行或运算一起发送出去
* @param: none
* @return: none
***********************************************************/
void LDC1000_init(void)
{
// SPI_Write(LDC1000_CMD_RPMAX<<8|0xff);
SPI_LDC_WriteReg(LDC1000_CMD_RPMAX,0x31); //配置Rp_MAX(0x01)寄存器
SPI_LDC_WriteReg(LDC1000_CMD_RPMIN,0x1b); //配置Rp_MIN(0x02)寄存器
SPI_LDC_WriteReg(LDC1000_CMD_SENSORFREQ,0x94); //配置Sensor Frequency(0x03)寄存器
SPI_LDC_WriteReg(LDC1000_CMD_LDCCONFIG,0x17); //配置LDC Configuration(0x04)寄存器
SPI_LDC_WriteReg(LDC1000_CMD_CLKCONFIG,0x00); //配置Clock Configuration(0x05)寄存器,
//使用TBCLK作为时钟源 //配置INTB为比较输出标志位(status of Comparator output)
SPI_LDC_WriteReg(LDC1000_CMD_THRESHILSB,0x50); //配置Comparator Threshold High(0x06)寄存器低8位
SPI_LDC_WriteReg(LDC1000_CMD_THRESHIMSB,0x14); //配置Comparator Threshold High(0x07)寄存器高8位
SPI_LDC_WriteReg(LDC1000_CMD_THRESLOLSB,0xC0); //配置Comparator Threshold Low(0x08)寄存器低8位
SPI_LDC_WriteReg(LDC1000_CMD_INTCONFIG,0x02); //配置INTB Pin Configuration(0x0A),
SPI_LDC_WriteReg(LDC1000_CMD_PWRCONFIG,0x01); //配置Power Configuration(0x0B)寄存器, //为Active Mode,使能转化
}

/**********************************************************
* @brief: 使用SPI读取LDC1000中的数据
* @param: none
* @return: none
***********************************************************/
void LDCRead(void)
{
// LDC_CSN_LOW();
ProximityData = 0;
FrequencyData = 0;
while(LDC_Read_IRQ()!=0)
printf(“read 1 failed!”);
DataRcv[0] = SPI_LDC_ReadReg(LDC1000_CMD_PROXLSB); //写入将要读取的Proximity Data LSB寄存器地址(0x21)
//printf(“0 %d\r\n”,DataRcv[0]);
//SPI_Read(&DataRcv[0]); //读取上述寄存器中的值,并存入DataRcv[0]
ProximityData|= DataRcv[0] ;
while(LDC_Read_IRQ()!=0)
printf(“read 2 failed!”);
DataRcv[1] = SPI_LDC_ReadReg(LDC1000_CMD_PROXMSB); //写入将要读取的Proximity Data MSB寄存器地址(0x22)
//printf(“1 %d\r\n”,DataRcv[1]);
//SPI_Read(&DataRcv[1]); //读取上述寄存器中的值,并存入DataRcv[1]
ProximityData|= (DataRcv[1]<<8) ; //组合成ProximityData
while(LDC_Read_IRQ()!=0)
printf(“read 3 failed!”);
DataRcv[2] = SPI_LDC_ReadReg(LDC1000_CMD_FREQCTRLSB); //写入将要读取的Frequency Counter Data LSB寄存器地址(0x23)
//printf(“2 %d\r\n”,DataRcv[2]);
//SPI_Read(&DataRcv[2]); //读取上述寄存器中的值,并存入DataRcv[2]
FrequencyData|= DataRcv[2] ;
while(LDC_Read_IRQ()!=0)
printf(“read 4 failed!”);
DataRcv[3] = SPI_LDC_ReadReg(LDC1000_CMD_FREQCTRMID); //写入将要读取的Frequency Counter Data Mid-Byte寄存器地址(0x24)
//printf(“3 %d\r\n”,DataRcv[3]);
//SPI_Read(&DataRcv[3]); //读取上述寄存器中的值,并存入DataRcv[3]
FrequencyData|= (DataRcv[3]<<8) ;
while(LDC_Read_IRQ()!=0);
DataRcv[4] = SPI_LDC_ReadReg(LDC1000_CMD_FREQCTRMSB); //写入将要读取的Frequency Counter Data MSB寄存器地址(0x25)
//printf(“4 %d\r\n\n\n”,DataRcv[4]);
//SPI_Read(&DataRcv[4]); //读取上述寄存器中的值,并存入DataRcv[4]
FrequencyData|= (DataRcv[4]<<16) ; //组合成FrequencyData

// LDC_CSN_HIGH();
}
//——————————————————//
//———————-Rp 计算————————-//
//————-unsigned long CountRp() —————–//
//——————————————————//
float CountRp(void)
{
float Y;
unsigned Code;
float Rp;

Code =ProximityData;

Y = ((float)Code/32768.0);
printf(“Y value: %f\r\n”,Y);
Rp = (float)(((float)TEST_RPMAX_MAX*(float)TEST_RPMAX_MIN) / ((float)TEST_RPMAX_MIN*(1-Y)+(float)TEST_RPMAX_MAX*(float)Y));

return Rp;
}

//——————————————————//
//——————-LC震荡频率求值——————–//
//—–unsigned long Fsensor(unsigned long lFcount)—–//、
//输入参数:lFcount: Fre Code的值
//——————————————————//
unsigned long Fsensor(unsigned long lFcount)
{
unsigned long lFsensor;
unsigned long Fcount;

Fcount = lFcount;
lFsensor = (1*Fext*ResponseTime)/(3*Fcount);

return lFsensor;
}
//——————————————————//
//———————L电感求值———————-//
//–unsigned long CountInductor(unsigned long lFsensor)-//
//输入参数:lFsensor: LC谐振频率
//——————————————————//
unsigned long CountInductor(unsigned long lFsensor)
{
unsigned long Fsensor;
unsigned long L;

Fsensor = lFsensor;

L = (unsigned long)(pow(10,12)* 1/(CapVal * pow(2*3.14*Fsensor,2)) ); //uH

return L;
}
extern void SPI_LDC_Init(void)
{
TIM3_Init();
MY_SPI_Init();
LDC1000_init();
flag=1;
}

/*
* 函数名:TIM3_NVIC_Configuration
* 描述 :TIM3中断优先级配置
* 输入 :无
* 输出 :无
*/
void TIM3_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

static void TIM3_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

}

static void TIM3_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

/* PWM信号电平跳变值 */
u16 TIM_CCR3_Val = 2;  /* -----------------------------------------------------------------------
TIME3 可以输出 4 路 PWM 波形:
TIME3_CH1   ------  PA6
TIME3_CH2   ------  PA7
TIME3_CH3   ------  PB0
TIME3_CH4   ------  PB1
----------------------------------------------------------------------- *//* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 3;       //当定时器从0计数到999,即为1000次,为一个定时周期
TIM_TimeBaseStructure.TIM_Prescaler = 0;        //设置预分频:预分频72,即为1KHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;    //设置时钟分频系数:不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);                                       /* 清除溢出中断标志 */
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);/* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;       //配置为PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM_CCR3_Val;      //设置跳变值,当计数器计数到这个值时,电平发生跳变
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR1_Val时为高电平TIM_OC3Init(TIM3, &TIM_OCInitStructure);     //使能通道1TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;       //配置为PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM_CCR3_Val;      //设置跳变值,当计数器计数到这个值时,电平发生跳变
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR1_Val时为高电平TIM_OC4Init(TIM3, &TIM_OCInitStructure);     //使能通道1TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);    //使用CCR3寄存器的影子寄存器(直到产生更新事件才发生更改)//TIM_ARRPreloadConfig(TIM3, ENABLE);            // 使能TIM3重载寄存器ARR/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);                   //使能定时器3

}

void TIM3_Init(void)
{
//TIM3_NVIC_Configuration();
TIM3_GPIO_Config();
TIM3_Mode_Config();
}

由于本人并不擅长PID,就不粘贴PID了,而且·PID和具体系统有关。

2016TI杯——寻迹小车相关推荐

  1. 关于寻迹小车组装建议

    太君组装寻迹小车 先说我碰到的问题: 焊接要注意,而且尽量先焊接再组装. 组装前应该先考考虑所有零件在小车上的布局. 每次接线时注意正负. 不要带电源组装. 修改电源线时请一根一根剪. 虽然有些常识我 ...

  2. 寻迹小车逻辑电路模块

    我们设计的小车是二路寻迹小车, 用了两个光电对管RPR220.小车的主要逻辑功能是是,如果左边的RPR220寻迹到黑线,左轮反转,右轮正转,实现左转;如果右边PRP2200寻迹到黑线,右轮反转,左轮正 ...

  3. STM32版CCD线性摄像头寻线寻迹小车

    基于STM32F103C8T6的CCD线性摄像头寻线寻迹小车 目录 基于STM32F103C8T6的CCD线性摄像头寻线寻迹小车 前言 一.模块介绍 二.使用说明 1.引脚说明 2.其他 三.调试过程 ...

  4. STM32红外寻迹小车

    STM32红外寻迹小车(寄存器版) 最近学习了STM32,想通过制作一辆小车来加深对STM32的理解,在平时学习时经常用正点原子提供的源代码稍加该装就行,但是正点原子没有提供关于红外寻迹模板的相关程序 ...

  5. 51“motorrr”寻迹小车学习1电机和寻迹模块

    目录 一 硬件 二 软件 前几天完成了寻迹小车的电机和寻迹模块的学习,这里板子用的是51最小系统板. 一 硬件 电机驱动模块L298N 和 寻迹模块 其实也没什么,pwm控制速度再加上寻迹模块,主要是 ...

  6. 基于51单片机的寻迹小车

    智能车刚入门,前段时间制作了一个51寻迹小车,就是网上那种寻迹是用四个红外传感器,驱动是L298N,主板是自己焊接的51最小系统加了一个7805将电池的7.2v稳压成5v(虽然我直接用的电池电压),原 ...

  7. 传感器实验——寻迹小车

    传感器实验--寻迹小车 防跌落小车实验 所选设备 寻迹小车 巡线原理 示例程序 之前我们用寻迹模块简单的做了一个防止小车高处跌落的功能,但是寻迹并不简单(/滑稽).本次我们使用寻迹来做一个巡线功能.简 ...

  8. FPGA入门实验-寻迹小车的实现

    任务目标 寻迹小车的实现.用的红外寻迹模块,记得要把模块可调电阻参数调好. 实现代码 电机模块代码motor.v: module MOTOR(input sysclk,input rst_n,inpu ...

  9. 红外寻迹小车基于K128单片机的红外对管飞思卡尔智能车(5个对管)程序部分

    红外寻迹小车基于K128单片机的红外对管飞思卡尔智能车(5个对管)软件部分包括: 出库 直行模块 大,小弯道 环岛 s弯 停车 #include "headfile.h" #inc ...

  10. Arduino与Proteus仿真实例-简单红外寻迹小车控制仿真

    简单红外寻迹小车仿真 1.寻迹小车介绍 红外寻迹小车是一种简单的Line Flower Robot(LFR)自主导向机器人,它会随地面上的线来检测白色表面上的暗线或黑色表面上的白线.LRF跟随线,因此 ...

最新文章

  1. 为啥led灯用一年后暗了很多_有些人日间车灯可以关为啥偏偏不关?是要告诉别人他的车好吗?...
  2. Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析
  3. UA STAT687 线性模型II 最小二乘理论2 约束最小二乘估计
  4. WPF 使用FontAwesome字体图标
  5. L1-026 I Love GPLT
  6. SQL SERVER 修改字段长度
  7. Kerberos下pyhive使用
  8. java写qq机器人插件_情迁QQ机器人JS插件/使用开发教程
  9. 全球著名编程大赛地址
  10. wps word设置多级标题及对应目录
  11. 微服务学习书籍推荐(从攻城狮到架构师进阶之路)
  12. 我所使用的五大返利网站使用比较
  13. php txt投票功能,php查询操作实现投票功能
  14. Hexo博客搭建以及主题使用
  15. html tbody边框,tbody边框呈现问题
  16. 【入门必备】如何学习一门编程语言——这些你一定要知道
  17. The word 'classpath' is not correctly spelled解决方法
  18. (差分)洛谷P4231 三步必杀
  19. (java)给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
  20. 三味眼中的十二“最”……

热门文章

  1. 三线压力传感器原理_压力传感器接线图及原理介绍
  2. 如何建设数据中台:精益数据创新体系
  3. JavaScript设计模式之策略模式-优化if条件过多
  4. linux服务器发异常包,如何排查Linux服务器上的恶意发包行为
  5. MSF Exploit入侵电脑实践(Win7/Win10皆可)
  6. 华三模拟器实现不同vlan之间的隔离,端口如何配置trunk模式
  7. 计算机网络的现状分析,计算机网络技术的发展现状和趋势分析.doc
  8. 匹配问题——匈牙利算法
  9. 代码运行:CornerNet源码
  10. cvs转datatable_C# CSV 文件转换成DataTable