找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2227|回复: 4
打印 上一主题 下一主题
收起左侧

基于STC32G12K128单片机的LCM-DMA-EEPROM实验例程

[复制链接]
跳转到指定楼层
楼主
      春节在家无事,学习了LCM,DMA和EEPROM的使用,写了一个例程,上机调试运行通过,分享给大家,相信这类东西多些对我们初学者是有利的。也欢迎大神们指点和吐槽。

      程序采用模块化编程,一个主程序main.c,一个mcu初始化程序mcu_initial,c。一个tft320x240屏的驱动程序。其余两个看名子就知是什么了。
下面是单片机主程序:
#include <STC32G.H>
#include "mcu_initial.h"
#include "picture.h"
#include "eeprom_drv.h"
#include "tft_320_drv.h"
#include "lcm_dma_test.h"
char xdata buffer[3696];//DMA缓冲区,按技术手册要求,必须在xdata位置
        void main(void)
{
unsigned int k;
        unsigned long cont;
//unsigned long j;

        mcu_initial();
        lcd_initial();
      
lcd_address(0,0,320,240);
        display_black();//不清屏的结果是屏上会显示上一个程序运行时的图像
/***清全部eeprom区,写完屏蔽掉,这里设置了37K的eeprom
        for(j=0;j<37887;j=j+512)
         IapErase(j);
        */
        /***先把数据写入eeprom
                p=gImage_picture;//gImage_picture是头文件中的图像数组的名

        for (j=0;j<36960;j++)
        {
                //dat=*p;//从目标位置取操作数据,本例是直接把数据源位置写入
                IapProgram(j,*p);//把数据写入指定位置
                p++;//源数据地址加一
               
        }
*/
//读eeprom数据文件并显示出来
for (cont=0;cont<10;cont++)
{
        IapReadmany(cont*3696,3696,buffer);//读一组数据,因为xdata空间限制,要分次读到,次数与每次的数量的积正好为全部数据,这个读取函数很厉害,一句就把需要的数据读到缓冲区了

        lcm_dma_test(0,(0+cont*12),154,120,3696,buffer);//分四个位置显示,因为空间限制,不能存下全屏用的数据,只存了四分之一幅
while(!(DMA_LCM_STA&0x01));//这时本应该做其它事,可我打算继续刷屏,所以只好等待
        lcm_dma_test(154,(0+cont*12),154,120,3696,buffer);
while(!(DMA_LCM_STA&0x01));
        lcm_dma_test(154,(120+cont*12),154,120,3696,buffer);
while(!(DMA_LCM_STA&0x01));
        lcm_dma_test(0,(120+cont*12),154,120,3696,buffer);
while(!(DMA_LCM_STA&0x01));

}


while(1)

{k=SEC;
digit_display(128,64,k);//显示时钟秒位
digit_display(160,96,MIN);//显示时钟分位,只为测试,随意显示的

        }
}

void LCMIF_DMA_Interrupt(void) interrupt 13
{
        if(DMA_LCM_STA& 0x01)//lcm中断请求标志位
        {
        //        LCMIFSTA = 0x00;//清中断标志位
                        DMA_LCM_STA = 0x00; //清除 DMA 状态
//LcmFlag = 0;
        }
        /***先屏蔽DMA内容
        if(DMA_LCM_STA & 0x01)//lcm的dma中断请求标志位
        {
                if(DmaFlag)
                {
                        DmaFlag = 0;
                        DMA_LCM_CR = 0;
                }
                else
                {
                        index--;
                        if(index == 0)
                        {
                                DMA_LCM_CR = 0;
                                LCD_CS=1;
                        }
                        else
                        {
                                DMA_LCM_CR = 0xa0;        //Write dat
                        }
                }
                DMA_LCM_STA = 0;
        }
        */
      
}
尽可能的使用了STC官方数据手册的例程。特别是中断程序,是照抄的。如果哪句在官方手册里没有,一定是我自己造改的。
tft_320_drv.c里的写数据函数:

void transfer_data(char data1)
{//LCM程序
      
        LCMIFDATL = data1;
        CS0=0;
        LCMIFCR = 0x85;                //Enable interface, write data1 out
while(LCMIFSTA==0);

LCMIFSTA=0;

        CS0 = 1 ;
      
//旧程序
/*        CS0 = 0;
        DC0 = 1;
        RD0 = 1;
        P2=data1;
        WR0 = 0;
        WR0 = 1;
        CS0 = 1;
        */
}

这是个基础函数,使用这个函数说明使用了LCM功能,这个功能能提高芯片的工作效率,这种用法就是把LCM功能日常化使用了。
这里附了一个旧函数,方便不能使用LCM功能的朋友使用其它两项功能(eeprom和dma).
STC官方数据手册上的写数据程序是这样的:
#define LCM_WRDB(d)  LCM_WR = 0;\  
                                       LCM_DB = (d);\
                                         _nop_();\
                                      LCM_WR = 1  

做为新人,看不太懂,但感觉是用了LCM这个名子,但没用LCM功能。
图像数据放在头文件Picture里,使用这个程序时需要自己做个图形数据的头文件。我自己的图不太严谨就不上传了。自己做图里要考虑图像的大小与屏,eeprom空间容量的关系,我用了一半的eeprom存了四分之一屏的图像。约37K。320*240*2/1024=37.5k
完整程序在附件中,欢迎查阅,吐槽和指正。
补充一句,stc32g12k128的eeprom容量是在stc-isp软件里设置的。如图所示的位置。

stc-isp.png (35 KB, 下载次数: 54)

stc-isp.png

例图.png (7.23 KB, 下载次数: 50)

例图.png

hard_test.zip

312.19 KB, 下载次数: 25, 下载积分: 黑币 -5

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1039438 发表于 2023-2-1 08:20 | 只看该作者
补充一下:
1,做为学习阶段的例程,程序中还使用了外晶振和内部RTC时钟源,没有安装外晶振的朋友可以把相关语句屏蔽掉,系统会自动选择内部高速时钟源,其频率可在STC-ISP软件界面选定。
2,缓冲数组的确定和程序中几个数字的解释,我在这个程序中用了一个随手拿来的图片,经软件(Image2Lcd或其它)缩小后大小为154*120(320和240两者只能照顾一个)。其数据量为:
154*120*2=36960(字节)
选择缓冲数组3696一是该 值小于8K(stc32g12k128的xdata空间是8K,DMA缓冲数组只能放在这个空间)
二是总数据量正好分十次读完(整除)。三是3696/154/2=12.就是刷屏时正好12行(整除),所以程序中出现了3696,154,120,12这几个数字,如果哪位同学的图像数据不同,可按这个关系自己确定相应的常数。
3,调试程序时借助了stc-usb link1d工具,进行硬件仿真,用它可以清楚地看到程序运行到哪一步,各种变量的变化,及数组内数值的变化。明显的减少了调试时间。记得听过一句话,说程序不是写出来的,是调出来的。意思大概是写一个程序并不难,但写完后难免存在各种小bug.一点小问题可能耽误很多时间,甚至调错方向,把对的改成错的,结果越调越乱(我这种新人难免出这种情况),有了硬件仿真,就容易多了。程序卡在哪里,一看就知道,针对性的进行调整,容易多了,记得卡的最多的是外晶振无法开启(这也是上来做补充说明的原因)到现在我也没能把控时钟管理。只到了能用的程度,出现问题时,没能力解决这方面的问题。而最夸张的一次是完全正确的程序,执行时却连第一行都没进去。如果没有硬件仿真器支持,真的要多花太多时间去查。
回复

使用道具 举报

板凳
ID:961114 发表于 2023-2-2 09:47 | 只看该作者
我也在学  
真12位ADC, 热敏电阻/NTC 测温 《STC32位8051单片机原理及C语言程序设计 视频教程》,第19集
回复

使用道具 举报

地板
ID:1039438 发表于 2023-2-3 13:10 | 只看该作者
STC庄伟 发表于 2023-2-2 09:47
我也在学  
真12位ADC, 热敏电阻/NTC 测温 《STC32位8051单片机原理及C语言程序设计 视频教程》,第19集

NTC的性能参数我不熟。没搞这方面的验证实验,只做了ds18b20的测温实验。
回复

使用道具 举报

5#
ID:1039438 发表于 2023-2-3 13:14 | 只看该作者
STC庄伟 发表于 2023-2-2 09:47
我也在学  
真12位ADC, 热敏电阻/NTC 测温 《STC32位8051单片机原理及C语言程序设计 视频教程》,第19集

后来才知道在屠龙刀核心板上就设计安装了NTC测温电路的,直接编程就能调试了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表