使用串口AT命令驱动点阵屏 VFD

本项目旨在做通用显示器件,直接利用串口发送数据即可显示,方便以后复用。显示屏RAV4拆机VFD,SPI驱动。MCUAtmega328p,使用其他mcu需要修改寄存器。串口波特率,115200,8n1。具体指令见注释。编译环境atmel studio 6.2

/************************************************************************
建立时间:2015.08.25
功能:串口输入指令和数据并在屏幕上显示。
指令: AT+L0=**********;第一行显示内容**********
        AT+L1=**********;第二行显示内容**********
        AT+L2=**********;第三行显示内容**********
        AT+L3=**********;第四行显示内容**********
        AT+PW=0;灯丝、高压关。
        AT+PW=1;灯丝、高压开。
        AT+BR=*;*:0-9设置亮度。0最低,9最高。
        AT+RE=1;VFD复位,重新初始化。
屏幕:RAV4车载cd拆机VFD
MCU:ATMEGA328P CRYSTAL :16MHZ
硬件连接:   en(灯丝电源、高压使能)》》PB1
            cs(SPI片选使能)》》PB2(SS)
            data(串行数据输入)》》PB3(MOSI)
            clock(SPI时钟)》》PB5(SCK)
修改时间:
修改内容:                                                                    
************************************************************************/

#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "zimo.h"

/************************************************************************/
/* 常量定义                                                             */
/************************************************************************/

#define cs PORTB2
#define en PORTB1


#define en_1() PORTB|=(1<<en)
#define en_0() PORTB&=~(1<<en)
#define cs_1() PORTB|=(1<<cs)
#define cs_0() PORTB&=~(1<<cs)


/************************************************************************/
/* 变量定义                                                             */
/************************************************************************/
#define Rx_Buffer_len 37 //显示数据区31+AT命令区6
unsigned int Rx_Buffer_Position;
unsigned char Rx_Buffer[Rx_Buffer_len];
unsigned char Rx_End_flag;
unsigned char AT_cmd;
/************************************************************************/
/* 初始化IO                                                             */
/************************************************************************/
void GPIO_Init(void)
{
    DDRB|=(1<<cs)|(1<<en);
}
/************************************************************************/
/* 串口初始化函数,115200 8 n 1,开串口接收中断使能                     */
/************************************************************************/
void USART_Init()
{
    cli();//关总中断
    /* Set baud rate 115200*/
    UBRR0H = (unsigned char)0;
    UBRR0L = (unsigned char)0x08;
    /* Enable receiver and transmitter and RX Complete Interrupt Enable*/
    UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
    /* Set frame format: 8data, 1stop bit */
    UCSR0C =(1<<UCSZ01)|(1<<UCSZ00);
    sei();//开总中断
    DDRD|=(1<<PORTD1);
}

/************************************************************************/
/* 串口数据发送,输入变量为字符                                         */
/************************************************************************/
void USART_Send( char data )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSR0A&(1<<UDRE0)) );
    /* Put data into buffer, sends the data */
    UDR0 = data;
}
/************************************************************************/
/* 串口发送字符串                                                       */
/************************************************************************/
void USART_Send_Str(char *s)
{
    while(*s)
    {
        USART_Send(*s);
        s++;
    }
}
/************************************************************************/
/* 清串口接受缓存数组                                                   */
/************************************************************************/
void Clear_Rx_Buffer()
{
    unsigned int i;
    for (i=0;i<Rx_Buffer_len;i++)
    {
        Rx_Buffer[i]=0x00;
    }
    Rx_Buffer_Position=0;
    Rx_End_flag=0;
    AT_cmd=0;
}
/************************************************************************/
/* 判断串口缓存区是否是AT指令                                           */
/************************************************************************/
void Check_Rx_buffer()
{
    if (Rx_Buffer[0]=='A'&&Rx_Buffer[1]=='T'&&Rx_Buffer[2]=='+'&&Rx_Buffer[5]=='=')
    {
        AT_cmd=1;
    }
    else
    {
        USART_Send_Str("AT False!");
        Clear_Rx_Buffer();
    }

}
/************************************************************************/
/* 串口中断程序讲收到的数据存入缓存数组,若数组满,从头开始             */
/************************************************************************/
ISR(USART_RX_vect)
{
    unsigned char rx_temp;

    rx_temp=UDR0;
    Rx_Buffer[Rx_Buffer_Position]=rx_temp;
    Rx_Buffer_Position++;

    if (Rx_Buffer_Position==Rx_Buffer_len)
    {
        Rx_Buffer_Position=0;
    }
    if (rx_temp==0x0d)
    {
        Rx_End_flag=0xff;   
        Check_Rx_buffer();
    }

}

/************************************************************************/
/* 功能:返回输入字符的索引地址0-61;若无,返回62                       */
/************************************************************************/
int Get_Index(unsigned char in_arr)
{
    unsigned char index;
    index=in_arr-0x20;
    if (index>94)
    {
        index=0;
    }
    return index;
}
/************************************************************************/
/* 初始化SPI接口    LSB&#x
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
配送一个自己写的串口驱动程序 用DMA接收数据 接收完会产生一个空闲中断 由此可判断接收完一个包的数据 再配送一个我自己写的动态内存管理 跟ESP8266的驱动 在项目中测试460800的波特率 30kb一秒的数据接收 一包1024个字节 每包需要应答15字节的情况下 AT指令处理是使用多个缓冲级来处理模块发送过来的数据 分别有模块应答缓冲级 跟等待应答的缓冲级、被忽略的AT指令集的缓冲级(例如注册一个SEND OK\r\n则模块应答此条指令立刻清除缓冲级释放内存无需等待超时直接忽略)还有需要回调的缓冲级(则出现此指令调用回调函数)都是通过注册的方式来实现 如果出现一包跟指令被分到一个包内 AT处理函数一样可以搜索到AT指令 使用strstr函数来实现 函数的缓冲级都是指针不占用内存 使用动态内存管理的方式 有数据则创建内存放入数据作为一个缓冲级 如果模块应答的数据在规定的时间内没有响应则删除此缓冲级 函数前都有注释介绍 下面介绍一些常用的函数: at_init初始化一些变量已经串口 at_time_task使用定时器回调 1毫秒回调一次 用来计数超时的指令缓冲&等待超时的计数 at_clear_all 在模块开机的时候可能会有很多乱数据 可以在初始化完毕后使用此函数清除所有缓冲级 释放所有内存 at_processing处理AT的应答超时的指令(做删除释放内存的动作),还有处理等待的AT指令 此函数一定要不断循环处理 可以加入到定时器 目前我实验是在UCOS上的 所以直接创建个任务来执行此函数 当程序在等待某个AT指令的时候此函数会寻找接收的缓冲级是否有等待的AT指令 at_cmd_cb_hand回调处理函数 如果接收缓冲级出现某个已经注册的指令则回调注册时所填写的函数地址 at_send_cmd 发送一个AT指令 可以用跟printf一样使用 %d等等 at_send_data 发送数据的时候所使用 需要填写长度 at_cmd_ignore_register 注册一个被忽略的AT指令 带入参数 *s (例如填写一个"SEND OK" 则模块应答的此条指令直接被忽略 释放内存 被忽略之前会检查此缓冲级会不会带有别的AT指令需要回调的) at_cmd_ignore_cancel 取消被忽略的指令 则取消已经注册的被忽略的AT指令 at_cmd_cb_register AT指令的回调注册 例如参数填写"+IPD",函数名a 则出现+IPD的时候回调a函数 a函数有类型 在at.h文件里面有 at_cmd_cb_cancel注销回调你懂得 at_wait_cmd 等待一个AT指令集或者超时则立刻返回 等待途中会不断调用OS的延迟程序 让系统能有时间去执行其他任务 使用方法例如{ at_send_cmd("AT+UART=%u,%u,%u,%u,%u\r\n",baudrate,databit,stopbit,parity,flow_control); return (esp_error)at_wait_cmd("\r\nOK\r\n",2000,NULL); } at_error at_wait2_cmd(char *s,char *s2,u16 timeout,u8 *index) 此函数是等待两个AT指令集 如果出现一个则立刻返回 返回值h文件有介绍 AT_DONE则出现此条指令 index参数则提取应答的缓冲首地址 使用at_buf_get函数获取首地址 使用完后要调用at_free_buf来清除并释放这个缓冲级 at_buf_len_get查询此应答的缓冲级长度 如果在index填写NULL则不需要缓冲级首地址 直接清除释放缓冲级

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值