⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dema.c

📁 这个是汽车制动台控制程序的C语言版本. 用于实际产品中.单片机用的是PIC16F877A.
💻 C
字号:
/*******************************************************************************************
* 对标定函数的说明:
*				1 与标定操作有关的按键: "WEIGH_DEMA","FORCE_DEMA"
*									 "ESC","ENSURE","MOVE","ADD_ONE"
*				2 进入标定的条件: "WEIGH_DEMA"或"FORCE_DEMA"按下超过5秒钟
*******************************************************************************************/
#include <pic.h>			//包含系统头文件
#include "total.h"			//包含项目头文件

////////////////////////////////////////////////////////////////////////////////////////////
void Send_C(bank3 unsigned char *ptr,unsigned char number)
{
	for (;number > 0; number--){
		while(TRMT == 0){
				;					//等待发送器为空
		}
		TXREG = *(ptr++);			//将要发送的数据装载到发数寄存器中
	}
}

/*******************************************************************************************
* 最近修改日期: 	05-4-14
* 修改原因: 		更改算法
* 修改人: 		饶阳胜
* 说明:			1 这种方法不好,是死循环
/*******************************************************************************************
* 函数名称: 	void Froce_Dema_Release(void)
* 功能: 		确认标键全部被松开
* 入口参数:  无
* 出口参数: 	无
* 全局变量:	无
* 调用模块:  无
* 设计者: 	饶阳胜
* 日期: 		05/3/4
* 说明: 
*******************************************************************************************/
void Dema_Release()
{
	while(1){
		while(1){
			if(ESC & MOVE & ENSURE & ADD_ONE & WEIGH_DEMA & FORCE_DEMA)  break;	//判断 标定、移位、确认、加1按键全部松开
		}
		Delay(D_SHAKE_H, D_SHAKE_L);	//去抖动延时
		if(ESC & MOVE & ENSURE & ADD_ONE & WEIGH_DEMA & FORCE_DEMA)	break;	//判断 标定、移位、确认、加1按键全部松开
	}
}

/*******************************************************************************************
* 最近修改日期: 	05-4-1
* 修改原因: 		增加可移植性
* 修改人: 		饶阳胜
/*******************************************************************************************
* 函数名称: 	void Clear_Zero(unsigned char SideSelect)
* 功能: 		校正0点
* 入口参数: 	*ptr		指向标定对象的指针
*			ad_change	当前0点的AD值
* 出口参数:	无
* 全局变量:	无
* 调用模块: 	无
* 设计者: 	饶阳胜
* 日期: 		05/3/17
* 说明: 		 ptr指针指向的第一个对象是:标定的点数
*				----------二-------:标定点的AD值
*				----------三-------:标定点的力值
*				后面依次类推
*******************************************************************************************/
void Clear_Zero(unsigned short *ptr,unsigned short ad_change)
{
	unsigned char i,j;

	ad_change -= ptr[1];								//现在0点 - 原来的0点
	for(i = 0,j = 1; i <= ptr[0]; i++,j += 2){			//对所有的标定进行调整
		ptr[j] += ad_change;							//更新标定点的AD值
	}
}		  

/*******************************************************************************************
* 最近修改日期: 	05-4-1
* 修改原因: 		简化代码
* 修改人: 		饶阳胜
/*******************************************************************************************
* 函数名称: 	unsigned char Dema(void)
* 功能: 		标定
* 入口参数:
* 出口参数: 	无
* 全局变量:
* 调用模块:
* 设计者: 	饶阳胜
* 日期: 		05-3-4
* 说明: 		1 轴重标定时,当前轴重在第0显示窗口显示
*			  制动力标定时,当前制动力值在第1个显示窗口显示
********************************************************************************************
* 修 改 人: 饶阳胜
* 日	   期: 06-3-16
* 原	   因: 增加实时发送数据,加在进入标定后.
*******************************************************************************************/
unsigned char Dema(short *ptr,unsigned char object,unsigned char address)
{
	unsigned char i;				
	unsigned short set_value;		//制动力设定值
	unsigned char bit_value;		//当前位的设定值
	unsigned char current_bit;		//当前的操作位
	static bit	flicker;			//利用此标志位,来实现当前设定位闪烁显示
	unsigned short temp;
	unsigned char point_number;		//标定点数
	unsigned short realtime;		// 

	display_data[0] = 0xFFFF;
	display_data[1] = 0xFFFF;
	display_data[2] = 0xFFFF;
	Display(display_data,DISPLAY_SIZE);			//所有显示变为"----",提示已进入轴重标定状态
	Dema_Release();								//等待按键松开

	if(object == WEIGH)
		display_weigh = 2; 						//打开显示轴重标识

//依据标定对象的不同,关闭相关的显示
	display_data[TWO] = 0xeeee;
	display_data[object ^ 0x01] = 0xeeee;

	i = 0;
	Init_Tmr1();
//进入制动力正式标定前的功能选项
	while(1){
		if(TMR1IF){
			Init_Tmr1();
			++i;
			if(i >= 3){
				i = 0;
				display_data[object] = Hex_Bcd(Count_Force(ptr,Adc_Adverage(object)));	//算出当前制动力

				if(object == WEIGH){
					send_buffer[0] = 0xf1;
				}else{
					send_buffer[0] = 0xf2;
				}
				send_buffer[1] = display_data[object] >> 8;
				send_buffer[2] = display_data[object];
				send_buffer[3] = 0xf3;
				Send_Computer(send_buffer,4);										//向上位机送果				
				
				Display(display_data,DISPLAY_SIZE);										//显示当前制动力				
			}
		}	
		if(!ESC){											//标定键按下
			Delay(D_SHAKE_H,D_SHAKE_L);						//去抖动延时
			if(!ESC){										//标定键确实被按下
				Dema_Release();								//等待按键被松开

//不知道是什么原因,如果只调用一次,写入的第一个字节的数据会出错,找不到原因
//不得已,调用了两次写EEPROM函数
				My_Write(ptr,DEMA_POINT_SIZE,address);
				My_Write(ptr,DEMA_POINT_SIZE,address);			//将制动力标定数据写到EEPROM中
				Normal_Display();
				return FALSE;								//标定返回
			}
		}else if(!ENSURE){									//确认键按下
			Delay(D_SHAKE_H,D_SHAKE_L);						//去抖动延时
			if(!ENSURE){
				Dema_Release();								//等待按键松开
				break;										//退出循环,进入标定
			}
		}else if(!ADD_ONE){									//加1键按下
			Delay(D_SHAKE_H,D_SHAKE_L);						//去抖动延时
			if(!ADD_ONE){
				Dema_Release();								//等待按键松开
				Clear_Zero(ptr,Adc_Adverage(object));		//调用清0函数
			}
		}
	}

//对控制参数初始化
	i = 0;
	point_number = 0;
	flicker	= 0;		
	bit_value = 0;
	current_bit = 3;
	set_value = 0;
	Init_Tmr1();

//正式进入标定状态
	while(1){
//判断要做何种操作
		if(!ESC){
			Delay(D_SHAKE_H,D_SHAKE_L);
			if(!ESC){												//标定键按下
				Dema_Release();

//不知道是什么原因,如果只调用一次,写入的第一个字节的数据会出错,找不到原因
//不得已,调用了两次写EEPROM函数
				My_Write(ptr,DEMA_POINT_SIZE,address);		
				My_Write(ptr,DEMA_POINT_SIZE,address);				//将制动力标定数据写到EEPROM中
				Normal_Display();
				return FALSE;		
			}
		}else if(!ENSURE){
			Delay(D_SHAKE_H,D_SHAKE_L);
			if(!ENSURE){											//确认键按下
				Dema_Release();
				if(point_number < 9){
					ptr[point_number * 2 + 1] = Adc_Adverage(object);	//存放当前标定点的AD值
																		//存放当前标定点的设定值,转换成16进制格式	,设定值为BCD码		
					ptr[point_number * 2 + 2] = Bcd_Hex(set_value);	
				}
				++point_number;
				if(point_number >= 2 && point_number != 0xa)
					ptr[0] = point_number;		
				if(point_number == 0xa){								//如果到达允许的标定点数,返回

//不知道是什么原因,如果只调用一次,写入的第一个字节的数据会出错,找不到原因
//不得已,调用了两次写EEPROM函数
					My_Write(ptr,DEMA_POINT_SIZE,address);
					My_Write(ptr,DEMA_POINT_SIZE,address);			//将制动力标定数据写到EEPROM中
					Normal_Display();
					return FALSE;
				}
				bit_value = 0;										//进入对下一点的标定,复位相关设定值
				current_bit = 3;
				set_value = 0x0;
			}
		}else if(!MOVE){
			Delay(D_SHAKE_H,D_SHAKE_L);
			if(!MOVE){												//移位键按下
				Dema_Release();
				--current_bit;										//操作位加1
				bit_value = 0;										//位设置值设定为0
				if(current_bit > 3){
					current_bit = 3;								//操作位溢出,刷新位操作	
				}	
			}
		}else if(!ADD_ONE){
			Delay(D_SHAKE_H,D_SHAKE_L);
			if(!ADD_ONE){											//加1键按下
				Dema_Release();
				++bit_value;										//位设定值加1
				if(bit_value > 9){
					bit_value = 0;									//位设定值溢出,位设定值清0
				}

				//将当前操作位的值填入制动设置变量中
				switch(current_bit){				
					case ZER0:										//当前设定位是最低位
						set_value &= 0xfff0;
						set_value |= bit_value;
						break;
					case ONE:										//当前设定位是次低位
						set_value &= 0xff0f;
						set_value |= bit_value << 4;
						break;
					case TWO:										//当前设定位是次高位
						set_value &= 0xf0ff;
						set_value |= bit_value << 8;
						break;
					case THREE:										//当前设定位是最高位
						set_value &= 0x0fff;
						set_value |= bit_value << 12;	
						break;
					default:										//出错
						break;
				}
				display_data[TWO] = set_value;
			}		
		}else if(TMR1IF ){									//检测闪烁时间是否已到
			// 每隔0.1秒向上位机发送实时数据
			realtime = Hex_Bcd(Count_Force(ptr,Adc_Adverage(object)));
			send_buffer[0] = '*';
			send_buffer[1] = (unsigned char)(realtime >> 12 & 0x0f) + '0';
			send_buffer[2] = (unsigned char)(realtime >> 8 & 0x0f) + '0';
			send_buffer[3] = (unsigned char)(realtime >> 4 & 0x0f) + '0';
			send_buffer[4] = (unsigned char)(realtime & 0x0f) + '0';
			send_buffer[5] = '#';
			Send_Computer(send_buffer, 6);					// 向上位机送数

			Init_Tmr1();									//更新TMR1设定
			i++;											//时间参数加1
			if(i >= 3){
//				display_data[object] = Hex_Bcd(Count_Force(ptr,Adc_Adverage(object)));	//算出当前制动力	
				display_data[object] = realtime;
				Display(display_data,DISPLAY_SIZE);								//开显示
				i = 0;										//时间已到,时间参数复位
				flicker ^= 0x1;								//标志位取反
				if(!flicker){
					display_data[TWO] = set_value;			//显示设定值
				}else{
					temp = set_value;
					switch(current_bit){				
						case ZER0:										//当前设定位是最低位
							temp &= 0xfff0;
							temp |= 0xe;
							break;
						case ONE:										//当前设定位是次低位
							temp &= 0xff0f;
							temp |= 0xe0;
							break;
						case TWO:										//当前设定位是次高位
							temp &= 0xf0ff;
							temp |= 0xe00;
							break;
						case THREE:										//当前设定位是最高位
							temp &= 0x0fff;
							temp |= 0xe000;	
							break;
						default:										//出错
							break;
					}
					display_data[TWO] = temp;				//显示屏蔽掉当前位的设定值
				}
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -