📄 示波器设计程序07-12-6.c
字号:
//ICC-AVR application builder : 2007-5-3 4:45:38
// Target : M16
// Crystal: 8.0000Mhz
/*ps:
连接方式:RST PB0
D/C PB2
SCE PB1
SDIN PB5
CLK PB7
*/
//示波器设计
//允许输入最大电压|2.4|v
//事例:输出一正弦波形,Vp_p=4.8v ,峰峰值满幅
#include <iom16v.h>
#include <macros.h>
//接口定义
#define LCD_DC_PIN 0x04 // PB2
#define LCD_CE_PIN 0x02 // PB1
#define LCD_RST_PIN 0x01 // PB0
#define SPI_MOSI_PIN 0x20 // PB5 SPI-MOSI
#define SPI_CLK_PIN 0x80 // PB7 SPI-SCK
#define uchar unsigned char
#define uint unsigned int
#define X_Length 84 //X轴数据长度
uchar X_Init;
uchar Y_Init;
uchar X_data=0;
uchar Y_data=2;
uchar temp; //有符号数
uchar result;
uchar count;
uchar temp1;
uchar temp2; //采样值高低位暂存
uint getdata; //采样值
/*-------------------------------------------------------------------------
-------------------- X轴描点坐标------------------------------------------*/
uchar const X_TAB[] =
{0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 1
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 2
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 3
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 4
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 5
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 6
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 7
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 8
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 9
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 10
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 11
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 12
0x80, 0x80, 0x80, 0x80, 0x80,0x00, // _ 13 */
0x80, 0x80, 0x80, 0x80, 0x80,0x00 };// _ 14
/*--------------Y轴描点坐标--------------------*/
uchar const Y_TAB[]={0x00, 0x00, 0x7F, 0x00, 0x00}; // |
/*--------------Z轴描点坐标--------------------*/
uchar const Z_TAB[] ={0x80, 0x40, 0x20, 0x10, 0x08,0x04, 0x02, 0x01};//由下到上
//uchar const K_TAB[] ={0x01, 0x02, 0x04, 0x08, 0x10,0x20, 0x40, 0x80};//从上到下
/*------------------------------
Public function prototypes
-------------------------------*/
void LcdInit ( void ); //初始化
void LcdClear ( void ); //LCD清屏
static void LcdSend ( uchar, uchar); //LCD数据发送
static void Delay ( void ); //延时
void LcdGotoXY (uchar, uchar ); //坐标
/*-----------------------------------------------------------------
Name : LcdInit LCD初始化
Description : Performs MCU SPI & LCD controller initialization.
-------------------------------*/
void LcdInit( void )
{
PORTB |= LCD_RST_PIN; //复位引脚为高电平
DDRB |= LCD_RST_PIN | LCD_DC_PIN | LCD_CE_PIN | SPI_MOSI_PIN |SPI_CLK_PIN;
Delay(); //short delay
PORTB &= ~LCD_RST_PIN; //上电复位;//复位引脚为低电平
Delay();
PORTB |= LCD_RST_PIN; //复位完; //
SPCR = BIT(SPE)|BIT(MSTR); //使能SPI,主机模式;
PORTB |= LCD_CE_PIN; //CE引脚为高电平
LcdSend( 0x21, 0 ); // LCD Extended Commands.
LcdSend( 0xC8, 0 ); // Set LCD Vop (Contrast).
LcdSend( 0x06, 0 ); // Set Temp coefficent.
LcdSend( 0x13, 0 ); // LCD bias mode 1:48.
LcdSend( 0x20, 0 ); // LCD Standard Commands, Horizontal addressing mode.
LcdSend( 0x0C, 0 ); // LCD in normal mode.
LcdClear();
}
/*-------------------------------------------------------------------------
Name : LcdClear
Description : Clears the display.
--------------------------------------------------------------------------*/
void LcdClear(void)
{
unsigned int i;
LcdSend(0x0c, 0);
LcdSend(0x80, 0); //此时默认操作为清屏
for (i=0; i<504; i++)
LcdSend(0, 1);
}
/*-----------------------------------------------------------------
Name : LcdGotoXY 设置块坐标
Description : Sets cursor location to xy location corresponding to basic font size.
-------------------------------*/
void LcdGotoXY(uchar X, uchar Y) //坐标轴的设置
{
LcdSend(0x40 | Y, 0); // column 列 64+y
LcdSend(0x80 | X, 0); // row 行 128+x
}
/*-----------------------------------------------------------------
Name : LcdSend
Description : Sends data to display controller.
Argument(s) : data -> Data to be sent
cd -> Command or data (see/use enum)
-------------------------------*/
static void LcdSend (uchar data, uchar command)
{
PORTB &= ~LCD_CE_PIN ; // 使能LCD
if (command == 0)
PORTB &= ~LCD_DC_PIN ; // 传送命令
else
PORTB |= LCD_DC_PIN ; // 传送数据
SPDR = data; // 传送数据到SPI寄存器
while ((SPSR & 0x80) == 0); // 等待数据传送完毕
PORTB |= LCD_CE_PIN ; // 关闭LCD
}
/*---------------------------------------------------------------
Name : Delay
Description : Uncalibrated delay for LCD init routine.
-----------------------------------------------------------------*/
static void Delay ( void )
{
uchar i;
for ( i = 0; i < 100; i++ );
}
/*---------------------------------------------------------------
Name : AD转换子程序
Description : 采用查询方式
-----------------------------------------------------------------*/
void ad_convert(void)
{
ADCSRA=0X86; //采用单次转换模式,ad使能,64分频
ADMUX=0Xc2; //选择通道2,选择内部参考电压,结果右对齐
ADCSR|=BIT(ADSC); //置一,启动转换
while((ADCSRA & 0x10)==0); //等待转换结束
ADCSRA|=0x10; //转换结束
ADCSRA&= ~(1 << ADEN); /*关闭转换*/
temp1=ADCL;
temp2=ADCH;
getdata=256*temp2+temp1; //10位采样值
/*运算*/
getdata=getdata>>2; //将采样的数据转换成电压
if(getdata >127) //转换成实际的坐标值0~47
getdata=(23+((getdata-128)*10)/53);
else if(getdata <=127)
getdata=(23-((128-getdata)*10)/53);
result=getdata;
}
/*-----------------------------------------------------------------
Name : coordinate
Description : 坐标定位子程序
------------------------------------------------------------------*/
void coordinate_init(void)
{ uchar X; //v=0,按行显示,x对应某个bank(0~83)
/*----------------------*/
/*----x轴显示-----------*/
X_Init=0;Y_Init=2; //x横向坐标
//for(X_Init=0;X_Init<14;X_Init++) //显示纵坐标
LcdGotoXY(X_Init,Y_Init); //0,2
for(X=0;X<X_Length;X++) //如果小于84,就一直输出数据
{
LcdSend(X_TAB[X],1); //取字模,显示横坐标
}
/*----x轴显示完毕-------*/
/*----------------------*/
/*----y轴显示-----------*/
X_Init=42;Y_Init=0; //y纵向坐标
for(Y_Init=0;Y_Init<6;Y_Init++) //显示纵坐标
{
LcdGotoXY(X_Init,Y_Init); //42,0
for(X=0;X<5;X++) //如果小于5,就一直输出数据
LcdSend(Y_TAB[X],1); //取字模
}
/*----y轴显示完毕---------*/
/*----------------------*/
}
/*-----------------------------------------------------------------
Name : //T/C中断
TIMER1 initialize - prescale:1024
WGM: 0) Normal, TOP=0xFFFF
desired value: 1Sec
actual value: 1.000Sec (0.0%)
------------------------------------------------------------------*/
void timer1_init(void)
{
TCCR1B = 0x00; //stop 无时钟源 T/C停止
TCNT1H = 0xf0; //setup 数据寄存器
TCNT1L = 0xbe;
TCCR1A = 0x00; //T/C控制寄存器 使用普通端口
TCCR1B = 0x04; //start Timer //1M经过256分频=3906Hz
//分频由后三位控制 010/ 8 011/64 100/256 101/1024
}
/*-----------------------------------------------------------------
Name :call this routine to initialize all peripherals
------------------------------------------------------------------*/
void init_devices(void)
{
CLI(); //disable all interrupts
timer1_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x1C; //timer interrupt sources /*定时器使用中断规则设定*/
//输出比较器A,B中断控制,一旦TIFR上的OCF1A置位 ,cpu开始执行a的
//中断程序。T/C溢出中断使能。
SEI(); //中断使能
}
/*-----------------------------------------------------------------
Name :wave_disp 任意波形显示
FUNCTION:还原波形,显示电气参数
------------------------------------------------------------------*/
void wave_disp (void)
{
if(result<8&&result>=0)
Y_data=5;
if(result<16&&result>=8)
Y_data=4;
if(result<24&&result>=16)
Y_data=3;
if(result<32&&result>=24)
Y_data=2;
if(result<40&&result>=32)
Y_data=1;
if(result<48&&result>=40)
Y_data=0;
LcdGotoXY(X_data,Y_data); //
LcdSend(Z_TAB[result%8],1); //取字模
X_data++;
if(X_data>83)
{
X_data=0;
LcdInit();//LCD初始化
coordinate_init();
}
}
/*-----------------------------------------------------------------
Name : //T/C中断
------------------------------------------------------------------*/
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void) //将每秒执行一次
{
TCNT1H = 0xf0; //reload counter high value 65536-57724=7812
TCNT1L = 0xbe; //reload counter low value 57724
ad_convert(); //调用AD程序
/*result++; //将其转换成0~47之间的数值
if(result>47)
result=0;*/
wave_disp(); //正弦波数据读取
}
/*-----------------------------------------------------------------
Name : main
------------------------------------------------------------------*/
void main(void)
{
LcdInit();//LCD初始化
init_devices();
coordinate_init();
while(1); //循环
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -