ABOV 程序 – 移动监测运动平台控制
文章目录
提示:ABOV 实现多机通信控制,来实现移动监测运动平台的控制
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、ABOV是什么?
ABOV半导体在2006年自韩国HYNIX分离出来,有超过20年单片机领域耕耘经验。ABOV半导体有单片机和标准IC另类产品
二、应用设定
1.应用场景设定
产品用于自动测试人体感应PIR对不同距离角度下感应效果
2.所使用的方法
1.Inventor 3维建模
2.ABOV单片机作为机械控制IC
IO输出 AD检测 串口通信
3.STM32单片机 作为系统终端控制IC
4.C# 作为电脑终端控制软件
3.最终实现的设定
实现对两台运动机构的控制,并完成机构上待测产品的测试 并将数据回传到多路终端
二、使用步骤
1.完成实验结构三维建模
主机构建模如下:
从机构建模如下:
两台构安装过后如下:
2.完成通信模式的构想
代码如下(示例):
3.完成从机调试
从机调试如下:
3.完成主机调试
三、从机制作
1.效果图
ABOV移动小车从机
ABOV从机移动效果
2.原理图
3.程序
代码生成器配置:
Keil完成代码后续:
OCD2完成仿真:
1.主程序
main.c:
//======================================================
// Main program routine
// - Device name : MC95FG308
// - Package type : 28SOP
//======================================================
// For XDATA variable : V1.041.00 ~
#define MAIN 1
// Generated : Fri, Nov 12, 2021 (21:10:31)
#include "MC95FG308.h"
#include "func_def.h"
#include "IO_code.h"
#include "usart_code.h"
#include "function_code.h"
void main()
{
cli(); // disable INT. during peripheral setting
port_init(); // initialize ports
clock_init(); // initialize operation clock
ADC_init(); // initialize A/D convertor
Timer0_init(); // initialize Timer0
UART_init(); // initialize UART interface
sei(); // enable INT.
// TODO: add your main code here
placeX_now = 0; //上电默认为0 坐标吧
while(1){
fn_function_check(); //在这里进行处理函数
// TODO: add other code here
}
}
//======================================================
// interrupt routines
//======================================================
void INT_USART0_Rx() interrupt 6
{
// USART0 Rx interrupt
// TODO: add your code here
dataR0 = UART_read(0);
fn_check_usart(0,&dataR0);
//UART_write(0,dataR0);
}
void INT_USART1_Rx() interrupt 10
{
// USART1 Rx interrupt
// TODO: add your code here
}
void INT_Timer0() interrupt 12
{
// Timer0 interrupt
// TODO: add your code here
Led_Time_Change(100);
}
void INT_ADC() interrupt 18
{
// ADC interrupt
// TODO: add your code here
}
void INT_BIT() interrupt 22
{
// BIT interrupt
// TODO: add your code here
}
//======================================================
// peripheral setting routines
//======================================================
unsigned char UART_read(unsigned char ch)
{
unsigned char dat;
if (ch == (unsigned char)0) { // UART0
while(!(USTAT & 0x20)); // wait
dat = UDATA; // read
}
if (ch == (unsigned char)1) { // UART1
while(!(USTAT1 & 0x20)); // wait
dat = UDATA1; // read
}
return dat;
}
unsigned int ADC_read()
{
// read A/D convertor
unsigned int adcVal;
while(!(ADCM & 0x10)); // wait ADC busy
adcVal = (ADCRH << 8) | ADCRL; // read ADC
ADCM &= ~0x40; // stop ADC
return adcVal;
}
void ADC_init()
{
// initialize A/D convertor
ADCM = 0x00; // setting
ADCM2 = 0x04; // trigger source, alignment, frequency
IEN3 |= 0x01; // enable ADC interrupt
}
void ADC_start(unsigned char ch)
{
// start A/D convertor
ADCM = (ADCM & 0xf0) | (ch & 0xf); // select channel
ADCM |= 0x40; // start ADC
}
void Timer0_init()
{
// initialize Timer0
// 8bit timer, period = 9.984000mS
T0CR = 0x96; // timer setting
T0DR = 0xE9; // period count
IEN2 |= 0x01; // Enable Timer0 interrupt
T0CR |= 0x01; // clear counter
}
void UART_init()
{
// initialize UART interface
// UART0 : ASync. 9615bps N 8 1
UCTRL2 = 0x02; // activate UART0
UCTRL1 = 0x06; // Async/Sync, bit count, parity
UCTRL2 |= 0xAC; // interrupt, speed
//UCTRL2 |= 0x10; // enable line when you want to use wake up in STOP mode
UCTRL3 = 0x00; // stop bit
UBAUD = 0x4D; // baud rate
// UART1 : ASync. 9615bps N 8 1
UCTRL12 = 0x02; // activate UART1
UCTRL11 = 0x06; // Async/Sync, bit count, parity
UCTRL12 |= 0xAC; // interrupt, speed
//UCTRL12 |= 0x10; // enable line when you want to use wake up in STOP mode
UCTRL13 = 0x00; // stop bit
UBAUD1 = 0x4D; // baud rate
IEN1 |= 0x11; // enable UART interrupt
}
void UART_write(unsigned char ch, unsigned char dat)
{
if (ch == (unsigned char)0) { // UART0
while(!(USTAT & 0x80)); // wait
UDATA = dat; // write
}
if (ch == (unsigned char)1) { // UART1
while(!(USTAT1 & 0x80)); // wait
UDATA1 = dat; // write
}
}
void clock_init()
{
// external clock
cli();
IEN3 |= 0x10; // Enable BIT interrupt
sei();
BCCR = 0x05; // 16msec BIT
SCCR = 0x81; // External clock
PCON = 0x03; // STOP1 mode entry
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCCR &= ~0x80; // clock changed
IEN3 &= ~0x10; // Disable BIT interrupt
}
void port_init()
{
// initialize ports
// 3 : AN4 in
// 8 : P10 out
// 9 : P11 out
// 16 : TxD1 out
// 17 : RxD1 in
// 19 : XIN in
// 20 : XOUT out
// 25 : TxD0 out
// 26 : RxD0 in
// 28 : P31 out
P0IO = 0xE7; // direction
P0PU = 0x08; // pullup
P0OD = 0x00; // open drain
P0DB = 0x00; // debounce
P0 = 0x00; // port initial value
P1IO = 0xFB; // direction
P1PU = 0x00; // pullup
P1OD = 0x00; // open drain
P1DB = 0x00; // debounce
P1 = 0x00; // port initial value
P2IO = 0xFE; // direction
P2PU = 0x00; // pullup
P2OD = 0x00; // open drain
P2DB = 0x00; // debounce
P2 = 0x00; // port initial value
P3IO = 0x7F; // direction
P3PU = 0x80; // pullup
P3OD = 0x00; // open drain
P3DB = 0x00; // debounce
P3 = 0x00; // port initial value
// Set port function
PSR0 = 0x10; // AN7 ~ AN0
PSR1 = 0x00; // I2C, AN14 ~ AN8
}
1.IO程序
IO_code.h :
#ifndef _IO_CODE_
#define _IO_CODE_
#include "MC95FG308.h"
#include "func_def.h"
#define TIME_Goforward 6 //时间为前进控制时间
#define TIME_GoBACK_Long 18 //时间为回退长控制时间
#define TIME_GoBACK_short 6 //时间为回退短控制时间
#define IO_Goforward P11 //IO口为前进控制口
#define IO_GoBACK P10 //IO口为后退控制口
unsigned int fn_IO_run(unsigned char distance); //前进控制程序
unsigned int fn_IO_goback(unsigned char back_time); //后退控制程序
void delay_ms(unsigned int count);
void delay_us(unsigned int count);
void delay_s(unsigned int count);
void Led_Time_Change(unsigned int count);
void Led_flash(void);
#endif
IO_code.c :
#include "IO_code.h"
#include "usart_code.h"
#include "function_code.h"
/************************************************************
* @brief
* unsigned int fn_IO_run(unsigned char distance)
* @param
* @retval
*************************************************************/
unsigned int fn_IO_run(unsigned char distance){ // 前进控制程序
unsigned char xdistance;
if(distance<=placeX_MIN){return 0;} // 前进不能小于最小位移坐标
for(xdistance=0 ;xdistance<distance ;xdistance++ ){
IO_Goforward = 1 ;
delay_s(1);
IO_Goforward = 0 ; //循环前进
delay_s(TIME_Goforward);
if(bdata_effect==1){ //中通接收到新的指令就出去了
return xdistance;
}
}
return xdistance;
}
/************************************************************
* @brief
* unsigned int fn_IO_goback(unsigned char back_time)
* @param
* @retval
*************************************************************/
unsigned int fn_IO_goback(unsigned char back_time){ // 后退控制程序
IO_GoBACK = 1 ;
delay_s(1);
IO_GoBACK = 0 ;
delay_s(back_time);
if(bdata_effect==1){
return 2;
}
return 0;
}
/************************************************************
* @brief
* void Led_Time_Change(unsigned int count)
* @param
* @retval
*************************************************************/
unsigned char count_Ledtime;
void Led_Time_Change(unsigned int count){ //中断定时器里IO闪烁
if(count_Ledtime++>count){
count_Ledtime=0;
P31 = ~P31;
}
}
/************************************************************
* @brief
* void Led_flash(void)
* @param
* @retval
*************************************************************/
void Led_flash(void){
P31 = ~P31;
delay_ms(100);
P31 = ~P31;
delay_ms(100);
P31 = ~P31;
}
/************************************************************
* @brief
* Delay 函数
* @param
* @retval
*************************************************************/
void delay_us(unsigned int count){
unsigned int a=0 ;
for(a=0;a<count;a++){
;
}
}
//-----------------------------------------------------
void delay_ms(unsigned int count){
unsigned int a=0,b=0;
for(a=0;a<count;a++){
delay_us(400);
}
}
void delay_s(unsigned int count){
unsigned int a=0,b=0;
for(a=0;a<count;a++){
delay_ms(1100);
if(bdata_effect==1){
return;
}
}
}
2.USAR串口程序
usart_code.c:
#ifndef _USART_CODE_
#define _USART_CODE_
#include "MC95FG308.h"
#include "func_def.h"
extern volatile unsigned char bdata_begin ;
extern volatile unsigned char bdata_judge ;
extern volatile unsigned char bdata_effect ;
extern volatile unsigned char bdata_error ;
#define _DATA_GET 0xAB
#define _DATA_GET_CODE 4
#define _DATA_GET_MODE 7
#define U_Scom_car 0xBA
#define U_Scom_code1 0x01 //开始
#define U_Scom_code2 0x02 //暂停
#define U_Scom_code3 0x03 //位移到目标坐标附件
#define U_Scom_code4 0x04 //开始测试目标坐标
#define U_Scom_code5 0x05 //返回起点
#define U_Scom_code6 0x06 //复位
#define U_Scom_code7 0x07 //故障
extern unsigned char UART_SENDCODE[_DATA_GET_CODE];
extern unsigned char dataR0 ;
extern unsigned char UART_GETcommand_car; //串口最终的设备地址
extern unsigned char UART_GETcommand_code; //串口最终的命令
extern unsigned char UART_GETcommand_X; //串口最终的X命令
extern unsigned char UART_GETcommand_Y; //串口最终的Y命令
void fn_usart_senddata(unsigned char ch, unsigned char *dat ,unsigned int num );
void fn_check_usart(unsigned char ch,unsigned char *dataget);
void fn_usart_sendcommande(unsigned char com_car, unsigned char com_code ,unsigned char com_X , unsigned char com_Y );
#endif
usart_code.c :
#include "usart_code.h"
#include "IO_code.h"
volatile unsigned char bdata_begin ;
volatile unsigned char bdata_judge ;
volatile unsigned char bdata_effect ;
//---------------------- 接收对应 码值 ---------------------------------
const unsigned char UART_GETCODE[_DATA_GET_MODE][_DATA_GET_CODE]=
{{0xAB,0x01,0x00,0x00},//开始
{0xAB,0x02,0x00,0x00},//暂停
{0xAB,0x03,0x00,0x00},//位移到目标坐标附件
{0xAB,0x04,0x00,0x00},//开始测试目标坐标
{0xAB,0x05,0x00,0x00},//返回起点
{0xAB,0x06,0x00,0x00},//复位
{0xAB,0x07,0x00,0x00}};//故障
volatile unsigned char uart_get_buffer[4]={0x00,0x00,0x00,0x00}; //串口接收端字节缓存器
//---------------------- 发送对应 码值存储器 ---------------------------------
volatile unsigned char UART_SENDCODE [_DATA_GET_CODE]={0xBA,0x01,0x00,0x00};
volatile unsigned char dataR0 = 0; //串口单字节缓存器
volatile unsigned char UART_GETcommand_car; //串口最终的设备地址
volatile unsigned char UART_GETcommand_code; //串口最终的命令
volatile unsigned char UART_GETcommand_X; //串口最终的X命令
volatile unsigned char UART_GETcommand_Y; //串口最终的Y命令
/************************************************************
* @brief
* void fn_usart_senddata( // 串口多数据发送函数 将单子节函数的发送程序进行封装
unsigned char ch, //串口编号
unsigned char *dat, //串口发送数据地址
unsigned int num ) //串口发送数据个数
* @param
* @retval
*************************************************************/
void fn_usart_senddata(unsigned char ch, unsigned char *dat ,unsigned int num ){
unsigned int i;
for(i=0 ; i<num ; i++){
UART_write(ch,dat[i]); //多字节写入操作
}
}
/************************************************************
* @brief
* static void fn_get_usart(
unsigned char ch, //串口编号
unsigned char *dataget) //串口单字节接收到的数据变量地址
* @param
* @retval
*************************************************************/
static void fn_get_usart(unsigned char ch,unsigned char *dataget){ //串口接收定制化函数
static unsigned char num_dataget; //静态记录个数变量
unsigned char data_dataget;
data_dataget = *dataget ;
if(ch == 0){ //USAR 0 串口
if(bdata_begin == 0){
uart_get_buffer[0]=0x00; // 清理指令缓存集变量空间
uart_get_buffer[1]=0x00;
uart_get_buffer[2]=0x00;
uart_get_buffer[3]=0x00;
if(data_dataget ==_DATA_GET){ //判断指令开始是否对应到了起始变量
bdata_begin =1;
bdata_judge = 0;
num_dataget = 0; //当识别到了特定指令 开始记录数据
}else{
num_dataget = 0; //识别到是否为 指令中开头关键字 _DATA_GET
bdata_judge = 0;
return;
}
}
uart_get_buffer[num_dataget++]=data_dataget; //对指令缓存器进行数据存储
if(num_dataget==_DATA_GET_CODE){ //记录制定长度的信号
bdata_begin =0;
num_dataget = 0;
bdata_judge = 1; // 信号被成功截取标志位
}
}
}
/************************************************************
* @brief
* static void fn_effect_usart(
unsigned char ch, //串口编号
unsigned char *dataget) //串口单字节接收到的数据变量地址
* @param
* @retval
*************************************************************/
static void fn_effect_usart(unsigned char ch,unsigned char *dataget){
unsigned char ndec=0; // 二维行坐标
unsigned char ndem=0; // 二维纵坐标
unsigned char effect_data=0; // 指令判断缓存器
unsigned char effect_data2=0; // 指令判断缓存器
if(ch==0){
if(bdata_judge==0){return;} // 信号被成功截取标志位
bdata_judge = 0;
for(ndem=0 ;ndem<_DATA_GET_MODE ;ndem++ ){ //遍历指令集对
for(ndec = 0;ndec<_DATA_GET_CODE-2 ;ndec++){ //减去2 因为 X Y指令不做判断
effect_data = dataget[ndec];
effect_data2 = UART_GETCODE[ndem][ndec];
if(UART_GETCODE[ndem][ndec] != dataget[ndec] ){ // 如果遍历到对应的指令位置
break;
}
if(ndec==_DATA_GET_CODE-1-2){ //如果判断4指令长度中两个指令对应上即 UART_GETcommand_car UART_GETcommand_code 对应上就可以存储指令了
UART_GETcommand_car = dataget[0]; //串口最终的设备地址
UART_GETcommand_code = dataget[1]; //串口最终的命令
UART_GETcommand_X = dataget[2]; //串口最终的X命令
UART_GETcommand_Y = dataget[3]; //串口最终的Y
fn_usart_senddata(0,dataget,_DATA_GET_CODE); //将截取到的正确指令返回主机
dataget[0]=0x00; // 存储过后清理缓存器
dataget[1]=0x00;
dataget[2]=0x00;
dataget[3]=0x00;
bdata_effect = 1; // 指令正式生效
return;
}
}
}
dataget[0]=0x00; //便利了半天没有找到对应的指令
dataget[1]=0x00;
dataget[2]=0x00;
dataget[3]=0x00;
}
}
/************************************************************
* @brief
* void fn_check_usart(
unsigned char ch, //串口编号
unsigned char *dataget) //串口单字节接收到的数据变量地址
* @param
* @retval
*************************************************************/
void fn_check_usart(unsigned char ch,unsigned char *dataget){ //对外判断接口函数对以上的程序进行封装
if(bdata_effect==1){return;}
fn_get_usart(ch , dataget);
fn_effect_usart(ch , uart_get_buffer);
}
/************************************************************
* @brief
* void fn_usart_sendcommande(
unsigned char com_car,
unsigned char com_code,
unsigned char com_X,
unsigned char com_Y )
* @param 指令发送函数
* @retval
*************************************************************/
void fn_usart_sendcommande(unsigned char com_car, unsigned char com_code ,unsigned char com_X , unsigned char com_Y ){
UART_SENDCODE[0] = com_car;
UART_SENDCODE[1] = com_code;
UART_SENDCODE[2] = com_X;
UART_SENDCODE[3] = com_Y;
fn_usart_senddata(0,UART_SENDCODE,_DATA_GET_CODE);
}
3.功能function
function_code.h:
#ifndef _FUNCTION_CODE_
#define _FUNCTION_CODE_
#include "MC95FG308.h"
#include "func_def.h"
#include "IO_code.h"
#include "usart_code.h"
#define placeX_MAX 6 //设备运行 的最远距离 单位米
#define placeX_MIN 0 //设备运行 的最进距离 单位米
extern volatile unsigned int placeX_now ; // 记录当前的位置 单位米
extern volatile unsigned int placeX_aim ; // 记录串口发来的数据位置 单位米
void fn_function_check(void); //行为动作函数
#endif
function_code.c:
#include "function_code.h"
#include "usart_code.h"
#include "IO_code.h"
volatile unsigned int placeX_now = 0;
volatile unsigned int placeX_aim = 0;
void fn_function_check(void){
if(bdata_effect==0){return;} // 串口识别到有效的数据标志位
bdata_effect = 0; // 清除串口识别到有效的数据标志位开始执行
IO_Goforward = 0; // 将前进的IO口关闭
IO_GoBACK = 0; // 将后退的IO口关闭
switch(UART_GETcommand_code){ //识别到的指令
case 0x01: //开始
placeX_now = 0; //初步设定当前位置为x=0
fn_usart_sendcommande(U_Scom_car, U_Scom_code1,placeX_now,0x00); //将发送车号,发送指令 当前坐标 返回给主机
break;
case 0x02: //暂停
fn_usart_sendcommande(U_Scom_car, U_Scom_code2,placeX_now,0x00);//将发送车号,发送指令 当前坐标 返回给主机
break;
case 0x03: //位移到目标坐标附件
if((UART_GETcommand_X<placeX_now)||(UART_GETcommand_X<placeX_MIN)||(UART_GETcommand_X>placeX_MAX)){
fn_usart_sendcommande(U_Scom_car, U_Scom_code3,0xFF,0xFF);break; //发送异常信号0xFF
} // 运动目标坐标不能小于当前坐标,不能低于最小坐标,不能高于最大坐标
placeX_aim = UART_GETcommand_X; //取得目标坐标
placeX_now += fn_IO_run(placeX_aim-placeX_now); // 设备开始运行并更新当前坐标
fn_usart_sendcommande(U_Scom_car, U_Scom_code3,placeX_now,0x00); //将发送车号,发送指令 当前坐标 返回给主机
break;
case 0x04: //开始测试目标坐标
if((UART_GETcommand_X<placeX_now)||(UART_GETcommand_X>placeX_MAX)||(UART_GETcommand_X<placeX_MIN+1)){
fn_usart_sendcommande(U_Scom_car, U_Scom_code4,0xFF,0xFF);break; //发送异常信号0xFF
} // 运动目标坐标不能小于当前坐标,不能低于最小坐标,不能高于最大坐标
placeX_aim = UART_GETcommand_X; //取得目标坐标
//---------------------------- 专注最后一步的测试 -------------------------
placeX_now += fn_IO_run(placeX_aim-placeX_now-1); //快速移动到待测试点前一个坐标
delay_s(2); //等待2秒进入目标一步的测试
placeX_now += fn_IO_run(placeX_aim-placeX_now); // 进入目标一步的测试
fn_usart_sendcommande(U_Scom_car, U_Scom_code4,placeX_now,0x00); //将发送车号,发送指令 当前坐标 返回给主机
break;
case 0x05: //返回起点
placeX_aim=0;
placeX_now = fn_IO_goback(TIME_GoBACK_Long); //执行返回复位行为
fn_usart_sendcommande(U_Scom_car, U_Scom_code5,placeX_now,0x00); //将发送车号,发送指令 当前坐标 返回给主机
break;
case 0x06: //复位
Led_flash();
placeX_aim=0;
if(placeX_now==0){
fn_IO_run(0x01); //向前一步走先要不就退后到墙上了
placeX_now = fn_IO_goback(TIME_GoBACK_short); //执行返回复位行为
}else{
placeX_now = fn_IO_goback(TIME_GoBACK_Long); //执行返回复位行为
}
fn_usart_sendcommande(U_Scom_car, U_Scom_code6,placeX_now,0x00); //将发送车号,发送指令 当前坐标 返回给主机
break;
case 0x07: //故障
bdata_effect = 0;
fn_usart_sendcommande(U_Scom_car, U_Scom_code7,placeX_now,0x00); //将发送车号,发送指令 当前坐标 返回给主机
break;
}
}
总结
未完待续。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
二维码