基本思路是将mega8串口接受到的信息先存入存储器(EEPROM)中,同时在LCD上显示两行,
每行15个字符,上下两行的最后一个字符用来显示箭头,指示是否还有未显示信息.
可以通过按键来进行翻页,无数据时相应的箭头就会消失.
还没做完就发现问题了,
存储器选用的是AT24CXX系列,通过IIC总线读取和写入.由于写入时间比较长,需要通过延时来等待写入操作完成.这样的话串口接受的数据就没法在比较高的速度下接收了.
实际测试在波特率为600bps的情况下,这个模拟终端可以使用.
呵呵,这样的速度确实忒慢了....
最近一直在想解决的方法...
等到有新的更好的方案再重新编写程序.....
不多说了,先把图和部分代码贴上来...
有点不清晰, 左上角的是5V电源,提供给MCU
紧挨着的下面是USB-232转换电路,右边的就是模拟串口终端电路了....
设置波特率的画面:
波特率设置为600bps:
等待串口发送数据:
部分源代码:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include "LCD1602.h"
/* Define UART variable */
//Baudrate value, 8 method for select. Fosc = 8MHz
#define Baud300 1
#define Baud600 2
#define Baud1200 3
#define Baud2400 4
#define Baud4800 5
#define Baud9600 6
#define Baud14400 7
#define Baud19200 8
/* Define IIC Variable */
#define IIC_ReStart() IIC_Start()
char PageTemp[17];
uint8_t TopPoint = 0;
uint8_t EndPoint = 0;
//Indicate whether the AT24C01 had full of data
bool CircularQueue = false;
/* Define KeyScan Variable */
uint8_t OldKeyNum = NULL;
uint8_t Key = NULL;
/* Define Display Variable */
char BufferBelow[16];//15 bit data, one bit to indicate end-point
char BufferAbove[16];
//Indicate how fast the data had been transmited
uint8_t BusyBit = 0;
//Indicate whether there have newest data
bool ChangeBit = false;
//Display up-arrow at the end of first line
#define PageupEnable() PutOneCharLCD(0,15,0x02)
//Display down-arrow at the end of the second line
#define PagedownEnable() PutOneCharLCD(1,15,0x03)
//Mark current read point
uint8_t ReadPoint = 0;
/* Port Initialization */
void PortInit(void)
{
DDRC &= ~((1<<PC5) | (1<<PC4));//IIC Port
PORTC |= (1<<PC5) | (1<<PC4);
DDRB &= ~((1<<PB1) | (1<<PB2) | (1<<PB3));//Key
PORTB |= ((1<<PB1) | (1<<PB2) | (1<<PB3));
}
/* Write up & down arrow to LCD */
void WriteArrow(void)
{
//Write up arrow to LCD CGRAM
WriteCmdBF(0x40 | (0x02 << 3));
WriteData(0x00);
WriteData(0x04);
WriteData(0x0E);
WriteData(0x15);
WriteData(0x04);
WriteData(0x04);
WriteData(0x04);
WriteData(0x00);
//Write down arrow to LCD CGRAM
WriteCmdBF(0x40 | (0x03 << 3));
WriteData(0x00);
WriteData(0x04);
WriteData(0x04);
WriteData(0x04);
WriteData(0x15);
WriteData(0x0E);
WriteData(0x04);
WriteData(0x00);
_delay_ms(10);
}
/* Key Scan */
uint8_t KeyScan(void)
{
static uint8_t NewKeyNum;
if((PINB&(1<<PB1)) == 0)
{
OldKeyNum = DOWN;
}
else if((PINB&(1<<PB2)) == 0)
{
OldKeyNum = UP;
}
else if((PINB&(1<<PB3)) == 0)
{
OldKeyNum = SEL;
}
//if key released, keyscan success
if((PINB & (1<<PB1)) && (PINB & (1<<PB2)) && (PINB & (1<<PB3)))
{
NewKeyNum = OldKeyNum;
OldKeyNum = NULL;
return NewKeyNum;
}
else
return NULL;
}
/* */
/* IIC */
/* */
void IIC_Init(void)
{
TWCR = 0x00;//Disable IIC while setting
TWBR = 0x2A;//Set baud rate
TWSR = 0x00;
TWCR = 0x04;//Enable IIC
}
//Put 'start' on IIC bus
void IIC_Start(void)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
loop_until_bit_is_set(TWCR,TWINT);
}
//Put 'stop' on IIC bus
void IIC_Stop(void)
{
TWCR |= (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
//Transmit data to slaver
void IIC_Write(uint8_t data)
{
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
loop_until_bit_is_set(TWCR,TWINT);
}
//Indicate Address & Length for read
void IIC_ReadPage(uint8_t Addr, uint8_t Bit)
{
for(uint8_t i = 0;i<Bit;i++)
PageTemp
= IIC_ReadByte(Addr + i);
PageTemp[Bit] = '\0';
}
/* */
/* UART */
/* */
//only write UBRR
void SetBaudRate(uint8_t BaudRate)
{
switch (BaudRate)
{
case Baud300:
{
UBRRL = 0x82;
UBRRH = 0x06;
PutStringLCD(1,0," 300bps,ER: 0%");
break;
}
case Baud600:
{
UBRRL = 0x40;
UBRRH = 0x03;
PutStringLCD(1,0," 600bps,ER: 0%");
break;
}
case Baud1200:
{
UBRRL = 0xA0;
UBRRH = 0x01;
PutStringLCD(1,0," 1200bps,ER:0.1%");
break;
}
case Baud2400:
{
UBRRL = 0xCF;
UBRRH = 0x00;
PutStringLCD(1,0," 2400bps,ER:0.2%");
break;
}
case Baud4800:
{
UBRRL = 0x67;
UBRRH = 0x00;
PutStringLCD(1,0," 4800bps,ER:0.2%");
break;
}
case Baud9600:
{
UBRRL = 0x33;
UBRRH = 0x00;
PutStringLCD(1,0," 9600bps,ER:0.2%");
break;
}
case Baud14400:
{
UBRRL = 0x22;
UBRRH = 0x00;
PutStringLCD(1,0,"14400bps,ER:0.8%");
break;
}
case Baud19200:
{
UBRRL = 0x19;
UBRRH = 0x00;
PutStringLCD(1,0,"19200bps,ER:0.2%");
break;
}
default: break;
}
}
//Baud rate select
void BaudRateSel(void)
{
//uint8_t Key = NULL;
uint8_t BaudRate = 0;
LCDispClear();
PutStringLCD(0,0,"Set Baud Rate...");
/* Disable UART while setting baud rate */
UCSRB = 0x00;
UCSRA = 0x00;
//Write to UCSRC;Character size: 8 bit
UCSRC = ((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0));
do{
Key = KeyScan();
switch (Key)
{
case UP:
{
if(BaudRate<8)
BaudRate++;
SetBaudRate(BaudRate);
break;
}
case DOWN:
{
if(BaudRate>1)
BaudRate--;
SetBaudRate(BaudRate);
break;
}
default: break;
}
_delay_ms(10);
}while((Key != SEL) || (BaudRate == 0));
/* Enable USART when setting finished */
//Receive interrupt Enable
UCSRB = ((1<<RXCIE) | (1<<RXEN) | (1<<TXEN));
PutStringLCD(0,0," UART Work at: ");
}
void ShowVersion(void)
{
LCDispClear();
PutStringLCD(0,0,"Designed by lhy");
PutStringLCD(1,0,"UARTerminal V1.0");
_delay_ms(3000);
PutStringLCD(1,0,"Pls press OK....");
_delay_ms(100);
do
{
Key = KeyScan();
}while(Key != SEL);
}