本帖最后由 乐此不疲 于 2022-12-10 21:25 编辑
最近一直在用STC32G屠龙刀的板子做驱动SSD1963-7寸TFT屏的测试,正常的硬件LCM接口应用程序已经完成调试,但DMA_LCM模式驱动却总是不能实现,现象为发送一包数据后就卡死了,请各位大神帮忙指点一下,先谢了!
部分例程如下:
- /*---------------------------------------------------------------------*/
- /* --- STC MCU Limited ------------------------------------------------*/
- /* --- STC 1T Series MCU Demo Programme -------------------------------*/
- /* --- Mobile: (86)13922805190 ----------------------------------------*/
- /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
- /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
- /* --- Web: www.STCMCU.com --------------------------------------------*/
- /* --- Web: www.STCMCUDATA.com ---------------------------------------*/
- /* --- QQ: 800003751 -------------------------------------------------*/
- /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
- /*---------------------------------------------------------------------*/
-
-
- /************* 功能说明 **************
-
- 本例程基于STC32G为主控芯片的实验箱进行编写测试。
-
- 使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
-
- edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
-
- LCM接口+DMA驱动液晶屏程序
-
- 8bit I8080模式, P6口接D8~D15
-
- sbit LCD_RS = P4^5; //数据/命令切换
- sbit LCD_WR = P4^2; //写控制
- sbit LCD_RD = P4^4; //读控制
- sbit LCD_CS = P3^4; //片选
- sbit LCD_RESET = P4^3; //复位
-
- LCM指令通过中断方式等待发送完成
-
- DMA设置长度256字节,通过中断方式判断传输完成
-
- 下载时, 选择时钟 24MHz (用户可自行修改频率).
-
- ******************************************/
-
- #include "..\..\comm\STC32G.h"
- #include "stdio.h"
- #include "intrins.h"
- #include "font.h"
-
- #define MAIN_Fosc 24000000L //定义主时钟
-
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
-
- sbit LCD_RS = P4^5; //数据/命令切换
- sbit LCD_WR = P4^2; //写控制
- sbit LCD_RD = P4^4; //读控制
- sbit LCD_CS = P3^4; //片选
- sbit LCD_RESET = P4^3; //复位
-
- //IO连接
- #define LCD_DataPort P6 //8位数据口
-
- //支持横竖屏快速定义切换
- #define USE_HORIZONTAL 0 //定义液晶屏顺时针旋转方向 0-0度旋转,1-90度旋转,2-180度旋转,3-270度旋转
-
- //画笔颜色
- #define WHITE 0xFFFF
- #define BLACK 0x0000
- #define BLUE 0x001F
- #define BRED 0XF81F
- #define GRED 0XFFE0
- #define GBLUE 0X07FF
- #define RED 0xF800
- #define MAGENTA 0xF81F
- #define GREEN 0x07E0
- #define CYAN 0x7FFF
- #define YELLOW 0xFFE0
- #define BROWN 0XBC40 //棕色
- #define BRRED 0XFC07 //棕红色
- #define GRAY 0X8430 //灰色
-
- #define DARKBLUE 0X01CF //深蓝色
- #define LIGHTBLUE 0X7D7C //浅蓝色
- #define GRAYBLUE 0X5458 //灰蓝色
- #define LIGHTGREEN 0X841F //浅绿色
- #define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
- #define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
- #define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)
-
- //定义LCD的尺寸
- #define LCD_W 240
- #define LCD_H 320
-
- #define DMA_AMT_LEN 2047 //n+1
-
- u16 POINT_COLOR=0x0000; //画笔颜色
-
- u16 index;
- //u16 xdata Buffer[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
- u16 xdata Color[DMA_AMT_LEN+1];
- bit DmaFlag;
- bit LcmFlag;
-
- typedef struct
- {
- u16 width; //LCD 宽度
- u16 height; //LCD 高度
- u16 id; //LCD ID
- u8 dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
- u8 wramcmd; //开始写gram指令
- u8 rramcmd; //开始读gram指令
- u8 setxcmd; //设置x坐标指令
- u8 setycmd; //设置y坐标指令
- }_lcd_dev;
-
- _lcd_dev lcddev;
-
- void delay_ms(u16 ms);
- void GPIO_Init(void);
- void LCM_Config(void);
- void DMA_Config(void);
- void LCD_Init(void);
- void Test_Color(void);
- void LCD_WR_DATA_16Bit(u16 Data);
- void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd);
- void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode);
- void LCD_direction(u8 direction);
-
- void main(void)
- {
- WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
- EAXFR = 1; //扩展寄存器(XFR)访问使能
- CKCON = 0; //提高访问XRAM速度
-
- P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
- P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
- P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
- P3M1 = 0x50; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
- P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
- P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
- P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
- P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
-
- GPIO_Init();
- LCM_Config();
- DMA_Config();
- EA = 1;
-
- LCD_Init(); //LCM初始化
-
- while(1)
- {
- Test_Color();
- }
- }
-
- void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
- {
- u16 i,j;
- u16 width=ex-sx+1; //得到填充的宽度
- u16 height=ey-sy+1; //高度
- LCD_SetWindows(sx,sy,ex,ey);//设置显示窗口
-
- for(j=0,i=0;i<=DMA_AMT_LEN;i++)
- {
- Color[i] = color;
- }
- index = 75; //(320 * 240 * 2) / 2048 = 75
- LCD_CS=0;
- DMA_LCM_CR = 0xa0; //Write dat
- while(!LCD_CS);
- }
-
- void Test_Color(void)
- {
- u8 buf[10] = {0};
-
- LCD_Fill(0,0,lcddev.width,lcddev.height,WHITE);
- Show_Str(20,30,BLUE,YELLOW,"LCM Test",16,1);delay_ms(800);
- LCD_Fill(0,0,lcddev.width,lcddev.height,RED);
- Show_Str(20,30,BLUE,YELLOW,"RED ",16,1);delay_ms(800);
- LCD_Fill(0,0,lcddev.width,lcddev.height,GREEN);
- Show_Str(20,30,BLUE,YELLOW,"GREEN ",16,1);delay_ms(800);
- LCD_Fill(0,0,lcddev.width,lcddev.height,BLUE);
- Show_Str(20,30,RED,YELLOW,"BLUE ",16,1);delay_ms(800);
- }
复制代码
- /*****************************************************************************
- * @name :void LCM_Config(void)
- * @date :2018-11-13
- * @function :Config LCM
- * @parameters :None
- * @retvalue :None
- ******************************************************************************/
- void LCM_Config(void)
- {
- LCMIFCFG = 0x84; //bit7 1:Enable Interrupt, bit1 0:8bit mode; bit0 0:8080,1:6800
- LCMIFCFG2 = 0x09; //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
- LCMIFSTA = 0x00;
- }
-
- /*****************************************************************************
- * @name :void DMA_Config(void)
- * @date :2020-12-09
- * @function :Config DMA
- * @parameters :None
- * @retvalue :None
- ******************************************************************************/
- void DMA_Config(void)
- {
- DMA_LCM_AMT = (u8)DMA_AMT_LEN; //设置传输总字节数(低8位):n+1
- DMA_LCM_AMTH = (u8)(DMA_AMT_LEN>>8); //设置传输总字节数(高8位):n+1
- DMA_LCM_TXAH = (u8)((u16)&Color >> 8);
- DMA_LCM_TXAL = (u8)((u16)&Color);
- // DMA_LCM_RXAH = (u8)((u16)&Buffer >> 8);
- // DMA_LCM_RXAL = (u8)((u16)&Buffer);
- DMA_LCM_STA = 0x00;
- DMA_LCM_CFG = 0x82;
- DMA_LCM_CR = 0x00;
- }
复制代码
- /*****************************************************************************
- * @name :void LCM_Interrupt(void)
- * @date :2018-11-13
- * @function :None
- * @parameters :None
- * @retvalue :
- ******************************************************************************/
- void LCMIF_DMA_Interrupt(void) interrupt 13
- {
- if(LCMIFSTA & 0x01)
- {
- LCMIFSTA = 0x00;
- LcmFlag = 0;
- }
-
- if(DMA_LCM_STA & 0x01)
- {
- 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;
- }
- }
复制代码
问题现象为调用Test_Color()函数后就卡在了函数LCD_Fill(0,0,lcddev.width,lcddev.height,WHITE);这里了。
问题一:想知道上述现象的原因,卡死的问题怎样解决
问题二:我感觉这个函数有些问题,但作为玩51单片机的菜鸟第一次学习DMA的应用对例程的问题就无法理解了。
|