OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6183|回复: 10

学习STM32 玩TFT屏 第三季

[复制链接]

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2012-6-21 23:20:29 | 显示全部楼层 |阅读模式
 好了,这一季我们来搞懂一下以下代码:

#define LCD_CS_SET  GPIOC->BSRR=1<<9    //片选端口          PC9
#define LCD_RS_SET GPIOC->BSRR=1<<8    //数据/命令            C8    
#define LCD_WR_SET GPIOC->BSRR=1<<7    //写数据    PC7
#define LCD_RD_SET GPIOC->BSRR=1<<6    //读数据    PC6
    
#define LCD_CS_CLR  GPIOC->BRR=1<<9     //片选端口          PC9
#define LCD_RS_CLR GPIOC->BRR=1<<8     //数据/命令            C8    
#define LCD_WR_CLR GPIOC->BRR=1<<7     //写数据    PC7
#define LCD_RD_CLR GPIOC->BRR=1<<6     //读数据    PC6

是啥意思.

其实 

GPIOC->BSRR=1<<9   就是   PCout(9)=1;

我们直接对GPIOC->BSRR置 1 比 在GPIOC->ODR置1会快很多.快多少,我还不清楚,应快一倍多.感觉刷屏快了一倍,到时我们写个代码用逻辑分析仪来量一下就清楚了.
我们现在只要知道 用GPIOC->BSRR=1<<X   比  PCout(X)=1;  快就是了.

同理:

LCD_CS_CLR  GPIOC->BRR=1<<9   等同  PCout(9)=0;

你们再去这个贴子:
http://www.openedv.com/posts/list/6133.htm
会更明白一点.


好,我们改一下   用如下代码:

#include "sys.h"
#include "usart.h"
#include "delay.h"


//快速IO
#define LCD_CS_SET  GPIOC->BSRR=1<<9    //片选端口          PC9
#define LCD_RS_SET GPIOC->BSRR=1<<8    //数据/命令            C8    
#define LCD_WR_SET GPIOC->BSRR=1<<7    //写数据    PC7
#define LCD_RD_SET GPIOC->BSRR=1<<6    //读数据    PC6
    
#define LCD_CS_CLR  GPIOC->BRR=1<<9     //片选端口             PC9
#define LCD_RS_CLR GPIOC->BRR=1<<8     //数据/命令                C8    
#define LCD_WR_CLR GPIOC->BRR=1<<7     //写数据    PC7
#define LCD_RD_CLR GPIOC->BRR=1<<6     //读数据    PC6
    
//慢速IO
#define LCD_CS PCout(9)  //片选端口           PC9
#define LCD_RS PCout(8)  //数据/命令            C8    
#define LCD_WR PCout(7)  //写数据  C7
#define LCD_RD PCout(6)  //读数据  C6

#define LCD_LED PCout(10)  //背光

//PB0~15,作为数据线
#define DATAOUT(x)   GPIOB->ODR=x;         //数据输出
#define DATAIN       GPIOB->IDR;           //数据输入

#define LCD_WR_DATA(data){\
LCD_RS_SET;\
LCD_CS_CLR;\
DATAOUT(data);\
LCD_WR_CLR;\
LCD_WR_SET;\
LCD_CS_SET;\
}


//写寄存器函数=>快
void LCD_WR_REG(u8 data)
LCD_RS_CLR;//写地址  
  LCD_CS_CLR; 
DATAOUT(data); 
LCD_WR_CLR; 
LCD_WR_SET; 
  LCD_CS_SET;   
}


void LCD_IO_Init(void)
  RCC->APB2ENR|=1<<3;//先使能外设PORTB时钟
  RCC->APB2ENR|=1<<4;//先使能外设PORTC时钟

RCC->APB2ENR|=1<<0;    //开启辅助时钟
JTAG_Set(SWD_ENABLE);  //开启SWD
 
//PORTC6~10  推挽输出 
GPIOC->CRH&=0XFFFFF000;
GPIOC->CRH|=0X00000333; 
GPIOC->CRL&=0X00FFFFFF;
GPIOC->CRL|=0X33000000;  
GPIOC->ODR|=0X07C0;   
//PORTB 推挽输出 
GPIOB->CRH=0X33333333;
GPIOB->CRL=0X33333333;   
GPIOB->ODR=0XFFFF;
}

////正常IO写 寄存器 函数
//void LCD_WR_REG(u8 data)
//{ 
// LCD_RS=0;//写地址  
//  LCD_CS=0; 
// DATAOUT(data); 
// LCD_WR=0; 
// LCD_WR=1; 
//  LCD_CS=1;   
//} 
//
////正常IO写 8位数据 函数
//void LCD_WR_DATA(u16 data)
//
//{
//LCD_RS=1;
//LCD_CS=0;
//DATAOUT(data);
//LCD_WR=0;
//LCD_WR=1;
//LCD_CS=1;
//} 


//写寄存器
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);  
LCD_WR_DATA(LCD_RegValue);       
}


//读寄存器
u16 LCD_ReadReg(u8 LCD_Reg)
{    
u16 t;
LCD_WR_REG(LCD_Reg);    //写入要读的寄存器号  
GPIOB->CRL=0X88888888;  //PB0-7  上拉输入
GPIOB->CRH=0X88888888;  //PB8-15 上拉输入
GPIOB->ODR=0XFFFF;      //全部输出高

LCD_RS=1;
LCD_CS=0;
//读取数据(读寄存器时,并不需要读2次)
LCD_RD=0;    
LCD_RD=1;
t=DATAIN;  
LCD_CS=1; 
 
GPIOB->CRL=0X33333333; //PB0-7  上拉输出
GPIOB->CRH=0X33333333; //PB8-15 上拉输出
GPIOB->ODR=0XFFFF;    //全部输出高
return t;  
}      

void LCD_init()                       //  LCD ID: 0xB505
{
LCD_WriteReg(0x0000,0x0000);
LCD_WriteReg(0x0000,0x0000);
LCD_WriteReg(0x0000,0x0000);
LCD_WriteReg(0x0000,0x0000);
LCD_WriteReg(0x00a4,0x0001);
delay_ms(20);   
LCD_WriteReg(0x0060,0x2700);
LCD_WriteReg(0x0008,0x0202);
LCD_WriteReg(0x0030,0x0214);
LCD_WriteReg(0x0031,0x3715);
LCD_WriteReg(0x0032,0x0604);
LCD_WriteReg(0x0033,0x0e16);
LCD_WriteReg(0x0034,0x2211);
LCD_WriteReg(0x0035,0x1500);
LCD_WriteReg(0x0036,0x8507);
LCD_WriteReg(0x0037,0x1407);
LCD_WriteReg(0x0038,0x1403);
LCD_WriteReg(0x0039,0x0020);
LCD_WriteReg(0x0090,0x001a);
LCD_WriteReg(0x0010,0x0000);
LCD_WriteReg(0x0011,0x0007);
LCD_WriteReg(0x0012,0x0000);
LCD_WriteReg(0x0013,0x0000);
delay_ms(20);
LCD_WriteReg(0x0010,0x0730);
LCD_WriteReg(0x0011,0x0137);
delay_ms(20);
LCD_WriteReg(0x0012,0x01b8);
delay_ms(20);
LCD_WriteReg(0x0013,0x0f00);
LCD_WriteReg(0x002a,0x0080);
LCD_WriteReg(0x0029,0x0048);
delay_ms(20);
LCD_WriteReg(0x0001,0x0100);
LCD_WriteReg(0x0002,0x0700);
LCD_WriteReg(0x0003,0x1230);
LCD_WriteReg(0x0008,0x0202);
LCD_WriteReg(0x000a,0x0000);
LCD_WriteReg(0x000c,0x0000);
LCD_WriteReg(0x000d,0x0000);
LCD_WriteReg(0x000e,0x0030);
LCD_WriteReg(0x0050,0x0000);
LCD_WriteReg(0x0051,0x00ef);
LCD_WriteReg(0x0052,0x0000);
LCD_WriteReg(0x0053,0x013f);
LCD_WriteReg(0x0060,0x2700);
LCD_WriteReg(0x0061,0x0001);
LCD_WriteReg(0x006a,0x0000);
//LCD_WriteReg(0x0080,0x0000);
//LCD_WriteReg(0x0081,0x0000);
LCD_WriteReg(0x0090,0X0011);
LCD_WriteReg(0x0092,0x0600);
LCD_WriteReg(0x0093,0x0402);
LCD_WriteReg(0x0094,0x0002);
delay_ms(20);
LCD_WriteReg(0x0007,0x0001);
delay_ms(20);
LCD_WriteReg(0x0007,0x0061);
LCD_WriteReg(0x0007,0x0173);
LCD_WriteReg(0x0020,0x0000);
LCD_WriteReg(0x0021,0x0000);   
LCD_WriteReg(0x00,0x22); 

LCD_LED=1;
}




int main(void)
{
  u16 i,j,k,FOX[5]={0x001F,0XF81F,0XFFE0,0X07FF,0xF800};
  
  Stm32_Clock_Init(9);
  delay_init(72);
  uart_init(72,9600);
  LCD_IO_Init();
  LCD_init();

 
  while (1) 
    {   
   
for (k=0;k<5;k++)
{
for (i=0;i<320;i++)
{
for (j=0;j<240;j++)
{

LCD_WriteReg(0x0020,j);  //X
LCD_WriteReg(0x0021,i);  //Y

LCD_WR_REG(0x22);

LCD_WR_DATA(FOX[k]);

    //delay_ms(1);    
}
      }
 }
}


看!!  是不是快了???  还可以更快,我们下一季再学

我的工作就是天天在玩
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-6-21 23:39:11 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

102

主题

318

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1876
金钱
1876
注册时间
2011-12-21
在线时间
545 小时
发表于 2012-6-22 09:04:59 | 显示全部楼层
支持楼主  写的好
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2012-6-22 12:38:48 | 显示全部楼层
"我们现在只要知道 用GPIOC->BSRR=1<<X   比  Cout(X)=1;  快就是了."

不一定的,可能是编译器没做好优化的问题,PCout宏定义里有计算,可能这点编译器没有做好优化,
实事上这两句代码生成的的最简汇编是一样的。
>
https://github.com/roxma
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2201
金钱
2201
注册时间
2012-2-8
在线时间
35 小时
发表于 2012-6-22 12:46:17 | 显示全部楼层
你把编译器的优化等级设置高一些,两种的速度就一样了,
两种方式生成的汇编都需要 movs , ldr 和 str 三条指令的。
https://github.com/roxma
回复 支持 反对

使用道具 举报

2

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2012-5-7
在线时间
8 小时
发表于 2012-6-22 15:11:27 | 显示全部楼层
呵呵,不管怎么样,楼主至少让我明白了他们的区别,呵呵,谢谢!
耐心做事,好好做人。O(∩_∩)O!
回复 支持 反对

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
 楼主| 发表于 2012-6-22 15:15:31 | 显示全部楼层
哇噻,偶回头看看
我的工作就是天天在玩
回复 支持 反对

使用道具 举报

2

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2012-5-7
在线时间
8 小时
发表于 2012-6-22 16:38:08 | 显示全部楼层
楼主字体太小了 啊,看的眼睛吃力哦,还是像前两季字体最好啊
耐心做事,好好做人。O(∩_∩)O!
回复 支持 反对

使用道具 举报

2

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2012-5-7
在线时间
8 小时
发表于 2012-6-22 16:52:56 | 显示全部楼层
#define LCD_WR_DATA(data){\
LCD_RS_SET;\
LCD_CS_CLR;\
DATAOUT(data);\
LCD_WR_CLR;\
LCD_WR_SET;\
LCD_CS_SET;\
}
楼主你这样定义,你可以实现??
耐心做事,好好做人。O(∩_∩)O!
回复 支持 反对

使用道具 举报

18

主题

128

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2013-2-4
在线时间
214 小时
发表于 2013-11-24 17:57:32 | 显示全部楼层
回复【9楼】liurenyin:
---------------------------------
不完全手册v2.1的p178有讲解
回复 支持 反对

使用道具 举报

14

主题

338

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
464
金钱
464
注册时间
2013-6-15
在线时间
15 小时
发表于 2013-12-28 00:35:40 | 显示全部楼层
回复【11楼】hjnuc:
---------------------------------
宏定义换行要加\
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-7 09:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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