重量测量

实验五  重量测量

一、实验目的和要求

掌握点阵式液晶显示屏的原理和控制方法,掌握点阵字符的显示方法。

掌握模拟/数字(A/D)转换方式,

进一步掌握使用C51语言编写程序的方法,使用C51语言编写实现重量测量的功能。

四、实验步骤

1. 阅读实验原理,掌握YM12864C的控制方式,编写出基本的输出命令和数据的子程序;

2. 掌握点阵字模的构成方式。使用字模软件PCtoLCD2002,设定正确的输出模式,生成点阵数据

3. 使用C51语言编写重量测量程序; 

4. 调零,满量程校准; 

5. 将编译后的程序下载到51单片机;

6. 在托盘中放上相应重量的法码,使显示值为正确重量。

五、实验原理和注意事项

1. 参考附录二,学习点阵式液晶显示屏的控制方法。

2. 在液晶显示中,自定义图形和文字的字模对应的字节表需要使用专门的字模软件来生成。可以使用PCtoLCD2002字模软件提取。

3. 字符点阵等数据,需要定义在code数据段中,具体原理参见示例程序设计部分。

4. 向LCM输出一个命令或数据时,应当在选通信号为高时准备好数据,然后延迟若干指令周期,再将选通信号置为低。

5 与A/D转换相关的寄存器

ADC_POWER:ADC电源控制位,0关1开。

SPEED1,SPEED0:模数转换器速度控制位,控制A/D转换所需时间。

ADC_FLAG:模数转换结束标志位,AD转换完后,ADC_FLAG=1,一定要软件清0。

ADC_START:模数转换器(ADC)转换启动控制位,1开始转换,转换结束后为0。

CHS2/CHS1/CHS0:模拟输入通道选择,选择使用P1.0~P1.7作为A/D输入。

5 与A/D转换相关的寄存器

ADC_RES、ADC_RESL: A/D转换结果寄存器,是特殊功能寄存器,用于保存A/D转换结果。

IE:中断允许寄存器(可位寻址)

EA:CPU的中断开放标志,EA=1,CPU开放中断,EA=0,CPU屏蔽所有中断申请。

EADC:A/D转换中断允许位。1允许0禁止。

IPH:中断优先级控制寄存器高(不可位寻址)。

IP:中断优先级控制寄存器低(可位寻址)。

A/D转换器的具体使用方法参见STC单片机指南的第九章。

6. 重量传感器采用压敏电阻。利用压敏电阻采集应变,产生变化的阻值。利用放大电路将其转化为电压值,通过数模转换将电压值转化成CPU处理的数字信号。传感器根据编制的程序将数字信号转换为砝码重量显示输出。











实验五
#include <reg52.h>
#include "intrins.h"
#define LCD_DATA P2
/*
	总体思路  
	AD转换可以有自己的中断信号  每次中断更新显示即可
*/
typedef unsigned char uchar;
typedef unsigned int uint;

uint mypage=2; //页面
uint timecount=0;//延时计数

uchar code zhong[]={}
uchar code liang[]=
(重量为:0123456789)
//**********AD转换模块申明**************
sfr PLASF = 0X9D;
sfr ADC_CONTR = 0XBC;
sfr ADC_RES = 0XBD;
sfr ADC_RESL = 0XBE;
sfr AUXR1 = 0XA2;
sfr IPH = 0XB7;
//bit ADC_FLAG = 0XBC^4;
//bit ADC_START = 0XBC^3;
bit EADC = 0XA8^5;
//*************AD 函数部分**************
#define ADC_POWER	0X80
#define ADC_FLAG	0X10
#define ADC_START	0X08
#define ADC_SPEEDLL	0X00
#define ADC_SPEEDL	0X20
#define ADC_SPEEDH	0X40
#define ADC_SPEEDHH	0X60
void InitUart();
void InitADC();
void InitADC_n(uchar n);
uint ADC_GET(uchar n);
void DelayMs(uint n);

//*********LCD显示模块申明***************
/*
注意时序问题  首先 使能端E 然后读写R_W  然后寄存器选择 RS  再然后是片选信号CS 最后才能得到数据或者写入数据
*/
sbit RST = P1^5;
sbit CS1 = P1^7;   //0有效选择左半屏
sbit CS2 = P1^6;   //0有效选择右半屏
sbit E = P3^3;     //下降沿时 写指令  和   写显示数据  高电平读显示数据
sbit R_W = P3^4 ;   //0表示写 1表示读   尚不清楚是电平触发还是跳变触发
sbit RS = P3^5;
sbit BUSY = P2^7;
sbit ON = P2^5;

//************LCD 函数部分************
void delay (uint m);
bit IsBusy();
void InitLcd(void);
void ChooseScreen(uint screen);
void SetCommand(uchar cmd);
void SetData(uchar bytedata);
void SetPage(uchar page);
void SetLine(uchar line);
void SetColumn(uchar column);
void SetPower(uchar power);
void Clear(uint);
void ShowWord(uchar screen,uchar page,uchar column,uchar *p);
void Show(uint weight);

//实现
/*Intital ADC sfr*/
void InitADC()
{
	PLASF = 0xff;
	ADC_RES = 0;
	ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
	DelayMs(2);
}

/*?n?????*/
void InitADC_n(uchar n)	
{
 	n &= 0x07;        	//
	AUXR1 |= 0x04;	    //高两位放ADC_RES  低8位放ADC_RESL
	PLASF = 1<<n;		//设置管脚
}
uint ADC_GET(uchar n)
{
void SetCommand(uchar cmd);
void SetData(uchar bytedata);
void SetPage(uchar page);
void SetLine(uchar line);
void SetColumn(uchar column);
void SetPower(uchar power);
void Clear(uint);
void ShowWord(uchar screen,uchar page,uchar column,uchar *p);
void Show(uint weight);

//实现
/*Intital ADC sfr*/
void InitADC()
{
	PLASF = 0xff;
	ADC_RES = 0;
	ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
	DelayMs(2);
}

/*?n?????*/
void InitADC_n(uchar n)	
{
 	n &= 0x07;        	//
	AUXR1 |= 0x04;	    //高两位放ADC_RES  低8位放ADC_RESL
	PLASF = 1<<n;		//设置管脚
}
uint ADC_GET(uchar n)
{
	uint adc_data;
	n &= 0x07;			//确保是0~7通道
	ADC_RES = 0;		//清空存储器
	ADC_RESL = 0;		
	ADC_CONTR = 0;		//清零控制寄存器
	ADC_CONTR |= (ADC_POWER|ADC_SPEEDLL|n|ADC_START);
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();         //延时4个时钟周期左右
	while(!((ADC_CONTR & ADC_FLAG) == 0x10))	   //等待转换结束
	adc_data = (ADC_RES&0x03)*256 + ADC_RESL;  //计算转换结果
	//adc_data = ADC_RESL;
	//adc_data=(adc_data-180)/2;
	adc_data = (adc_data-146)/2;
	return adc_data ;    //adc_data
}


void DelayMs(uint n)
{
	uint x;
	while(n--)
	{
		x = 5000;
		while(x--);
	}
}

void delay(uint m)    //延时函数
{
	while(--m);
}

bit isBusy(){        //C51中没有布尔类型 可以用 bit来代替  hiahia 大发现
	bit flag;
	P2 = 0X00;
	RS = 0; R_W = 1; E = 1;
	flag = P2^7;
	E = 0;
	return flag;
}

void Read_busy()  //等待BUSY=0
{      			  //busy p2^7
	P2=0x00;
	RS=0;//RS/RW=0/1,读取状态字指令
	R_W=1;
	E=1;//控制LCM开始读取
	while(P2&0x80);//判忙,循环等待P2.7=0.
	E=0;//控制LCM读取结束
}

void ChooseScreen(uint n){
	switch(n)
  {
    case 0: CS1=1;CS2=1;break; //  全屏
		case 1: CS1=1;CS2=0;break; //  左屏
		case 2: CS1=0;CS2=1;break; //  右屏
		default: CS1=1;CS2=1;break;
  }
}

void SetCommand(uchar cmd){
	P2 = 0Xff;
	//while(IsBusy());
	Read_busy();
	RS=0;  R_W=0;
	P2 = cmd;
	E=1;
	delay(100);
	E=0;
}

void SetData(uchar bytedata){
	P2 = 0xff;
	//while(IsBusy());
	Read_busy();
	RS = 1;  R_W = 0;
	P2 = bytedata;
	E = 1;
	delay(100);
	E = 0;
}

void SetPage(uchar page){  //输入page 高五位 全零即可
	page = 0xb8|page;
	SetCommand(page);
}
void SetLine(uchar line){
	line = 0xc0|line;  //11000000|line
	SetCommand(line);
}

void SetColumn(uchar column){
	column=column&0x3f;//  高两位清零
  column=0x40|column;//01000000|column
	SetCommand(column);
}

void SetPower(uchar power){
	power = 0x3e|power;
	SetCommand(power);
}

void Clear(uint screen){
	uchar i,j;
	ChooseScreen(screen);
	for(i=0;i<8;i++){
		SetPage(i);
		SetColumn(0x00);
		for(j=0;j<64;j++){
			SetData(0x00);
		}
	}
}
void initLcd(void){
	//while(IsBusy());
	Read_busy();
	ChooseScreen(0);
	SetPower(0);
	ChooseScreen(0);
	SetPower(1);
	ChooseScreen(0);
	Clear(0);
	SetLine(0);
}

void ShowWord(uchar screen,uchar page,uchar column,uchar *array){
	int i;
	ChooseScreen(screen);
	SetPage(page);         //选上半子
	SetColumn(column);     //选定列数
	for(i=0;i<16;i++){     //上半个字
		SetData(array[i]);
	}
	SetPage(page+1);       //选下半字
	SetColumn(column);     //选定列数
	for(i=0;i<16;i++){     //下半个字
		SetData(array[i+16]);
	}
}

void Show(uint weight){
	uchar a,b,c;
	ShowWord(1,mypage,0*16,zhong);    	//重
	ShowWord(1,mypage,1*16,liang);    	//量
	ShowWord(1,mypage,2*16,wei);    	//为
	ShowWord(1,mypage,3*16,mao);      //:
	a = weight/100;
	b = weight%100/10;
	c = weight%10;
	switch(a){
		case 0: ShowWord(2,mypage,0*16,ling);break;
		case 1: ShowWord(2,mypage,0*16,yi);break;
		case 2: ShowWord(2,mypage,0*16,er);break;
		case 3: ShowWord(2,mypage,0*16,san);break;
		case 4: ShowWord(2,mypage,0*16,si);break;
		case 5: ShowWord(2,mypage,0*16,wu);break;
		case 6: ShowWord(2,mypage,0*16,liu);break;
		case 7: ShowWord(2,mypage,0*16,qi);break;
		case 8: ShowWord(2,mypage,0*16,ba);break;
		case 9: ShowWord(2,mypage,0*16,jiu);break;
	}
	switch(b){
		case 0: ShowWord(2,mypage,1*16,ling);break;
		case 1: ShowWord(2,mypage,1*16,yi);break;
		case 2: ShowWord(2,mypage,1*16,er);break;
		case 3: ShowWord(2,mypage,1*16,san);break;
		case 4: ShowWord(2,mypage,1*16,si);break;
		case 5: ShowWord(2,mypage,1*16,wu);break;
		case 6: ShowWord(2,mypage,1*16,liu);break;
		case 7: ShowWord(2,mypage,1*16,qi);break;
		case 8: ShowWord(2,mypage,1*16,ba);break;
		case 9: ShowWord(2,mypage,1*16,jiu);break;
	}
	switch(c){
		case 0: ShowWord(2,mypage,2*16,ling);break;
		case 1: ShowWord(2,mypage,2*16,yi);break;
		case 2: ShowWord(2,mypage,2*16,er);break;
		case 3: ShowWord(2,mypage,2*16,san);break;
		case 4: ShowWord(2,mypage,2*16,si);break;
       }
		case 5: ShowWord(2,mypage,2*16,wu);break;
		case 6: ShowWord(2,mypage,2*16,liu);break;
		case 7: ShowWord(2,mypage,2*16,qi);break;
		case 8: ShowWord(2,mypage,2*16,ba);break;
		case 9: ShowWord(2,mypage,2*16,jiu);break;
	}
	ShowWord(2,mypage,3*16,ke);
	DelayMs(50);
}

//******************************************

void initAD(){
	PLASF = 0X01;   //选择第0位作为模拟输入
	ADC_CONTR = 0X10;
	EA = 1;
	ADC_RES = 0X00;
	ADC_RESL = 0X00;
	EADC = 1;       //AD转换允许
}

void main(){
	InitLcd();
	InitADC();
	Clear(0);
	SetLine(0);
	while(1){
		uint ad = 0;
		InitADC_n (0);
		ad = ADC_GET(0);
		Show(ad);
	}
}




  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值