本帖最后由 tbnet 于 2015-9-18 18:17 编辑
51-彩屏初始化.zip
(33.35 KB, 下载次数: 82)
STM32-彩屏初始化.zip
(6.12 MB, 下载次数: 1558)
删除
各位大师:帮忙看看此程序问题出在哪里?为何下载到
开发板没反应呢?
开发板用的是普中科技的HC6800EM3,3.2寸彩屏的IC是R61509V,用的是8位数据接口,接PB8-15,此程序是通过51的程序改的,51的程序可以用,但是
STM32的程序用不了,找了两个星期了,实在找不到问题出在哪里?
附件的两个文件:一个为可以运行的51
单片机彩屏初始化程序,另一个为有问题的STM32程序。其主要内容见下面:
/*1.*RCC配置****************************************************************************************
**************************************************************************************************/
void RCC_PLL3_Configura
tion(void)
{
/****1.SYSCLK时钟源配置**********************************************************************************/
//1.复位RCC外部设备寄存器到默认值(打开HSI时钟线路,其它的一律关闭)
RCC_DeInit();
//2.打开外部高速晶振 HSE
RCC_HSEConfig(RCC_HSE_ON);
//3.等待外部高速HSE时钟准备好
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //
FLASH_SetLatency(FLASH_Latency_2); // 这两句还搞不懂是啥意思。
/****2.设置PLL锁相环**********************************************************************************/
//4.设置PLL锁相环时钟源,配置PLL倍频, (HSI走1分频线路,PLL倍频为9)
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //RCC_PLLSource_HSI_Div2 表示: PLL 的输入时钟 = HSI时钟频率除以 2 ; RCC_PLLMul_9
//RCC_PLLSource_HSE_Div1 表示: PLL 的输入时钟 = HSE时钟频率
//RCC_PLLSource_HSE_Div2 表示: PLL 的输入时钟 = HSE 时钟频率除以 2
//5.使能PLL时钟
RCC_PLLCmd(ENABLE);
//6.等待PLL时钟就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
//7.配置系统时钟 = PLL时钟 (将SYSCLK时钟线路设置为PLLCLK线路)
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//8.等待SYSCLK时钟从HSI线路转换至PLLCLK线路完成;(检查PLL时钟是否作为系统时钟)
while(RCC_GetSYSCLKSource() != 0x08)
{
}
/****3.设置各预分频器**********************************************************************************/
//9.配置AHB(HCLK)时钟=SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB预分频为1
//10.配置高速APB2(PCLK2)钟=AHB时钟
RCC_PCLK2Config(RCC_HCLK_Div1); //APB2预分频为1
//11.配置低速APB1(PCLK1)钟=AHB 1/2时钟 //APB1预分频为2
RCC_PCLK1Config(RCC_HCLK_Div2);
//12.此处可增加打开CSS监视系统。
/*****4.开启相应的外设时钟*********************************************************************************/
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能APB2外设的GPIOA的时钟
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能APB2外设的GPIOB的时钟
}
#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f10x.h"
extern void delay_init(void);
extern void delay_us(u32 nus); //微秒
extern void delay_ms(u16 nms); //毫秒
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// 一.用查询法实现delay_us(u32 nus); //微秒级延时
// delay_ms(u16 nms); //毫秒级延时
// 二.用查询法实现delay延时的步骤:
//////////////////////////////////////////////////////////////////////////////////////////////
#include "delay.h"
// static u8 fac_us=0;//us延时倍乘数 //定义fac_us为U8类型的全局变量Static就是定义fac_us为全局变量
u8 fac_us=0;
// static u16 fac_ms=0;//ms延时倍乘数
u16 fac_ms=0;
void delay_init()
{
/******************************************1.1配置Systick系统时钟************************************************************************************/
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟HCLK/8//假如HCLK(SystemCoreClock)=72MHz,则Systick=HCLK/8=9MHz;
/******************************************1.2计算 微秒数 装载数值的因子***************************************************************************/
fac_us=SystemCoreClock/8000000; //系统时钟/8000000=72MHz/8000000=72000000/8000000=9;
//上面这句的写法较难理解:假如系统时钟为72MHz时;可以直接写成:fac_us=9; 但是当系统时钟为36MHZ时
//则SysTick时钟为36/8=4.5MHz;则一个SysTick时钟周期为:1/(4.5*1000000);当其因子为4.5时:4.5/(4.5*1000000)=1/1000000=1毫秒;
//为了便于当系统时钟改变时;不用重新设置因子;将其写成:fac_us=SystemCoreClock/8000000; 是否也可写
//为:fac_us=SysTickCoreClock/1000000;呢,待验证
/******************************************1.2计算 毫秒数 装载数值的因子***************************************************************************/
fac_ms=SystemCoreClock/8000; //1微妙*1000=1毫秒 //解释含义同上 8000
}
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//A):给SysTick->LOAD装载值。
//假如延时1毫秒,则装载的值为1*fac_ms,假如要延时的值为nms毫秒,则为nms*fac_ms毫秒。
SysTick->VAL =0x00; //B):清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //C):开启计数器开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16))); //D):等待设定的时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //E):关闭计数器
SysTick->VAL =0X00; //F):清空计数器
}
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
#ifndef __LCD_H
#define __LCD_H
#include"stm32f10x.h"
#define uchar unsigned char
#define uint unsigned int
//#define TYPE_LCD_DATA 1
#define TYPE_LCD_COMMAND 0 //定义TYPE_LCD_COMMAND为常量0
#define LCD_SIZE_X 240 //定义LCD_SIZE_X为240 (原值为128)
#define LCD_SIZE_Y 400 //定义LCD_SIZE_Y为400(原值为160)
//#define DATA P0 //定义P0(pB8-15)口为数据端口
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define LCD_WR PBout(2) //PB2 LCD_WR = P2^5; //液晶读/写控制 /WR
#define LCD_RD PBout(1) //PB1 LCD_RD = P2^6; //寄存器选择输入 /RD
#define LCD_CS PBout(0) //PB0 LCD_CS = P2^7; //液晶使能控制 /LCDE
#define LCD_RS PAout(8) //PA8 LCD_RS = P3^2; //RS 引脚定义 /CS1
#define LCD_RST PAout(11) //PA11 LCD_RST = P3^3; //RST 引脚定义 /CS2
void LCD_init(void);
void LCD_clear(u8 x);
void LCD_GPIO_Init(void);
extern u16 colors[];
#endif
/**************************************************************************************
* *
* 3.2寸彩屏R61509V驱动 *
* 连接方法: 将3.2寸彩屏插入12864插槽(8位数据接接口PB8-15) *
* *
***************************************************************************************/
#include "delay.h"
#include "lcd.h"
/**********************************************************
写命令与数据子函数
**********************************************************/
void LCD_Write(uchar type, uint value) //变量type判定写入的是command还是data,变量value表示写入的内容
{
LCD_CS = 0;
LCD_RS = type; // 0: command 1: data
LCD_WR = 0;
//传送u16变量value高8位数据
GPIOB->ODR &= 0X00ff; //将高8位清0
GPIOB->ODR |= value&0xff00; //传送value高8位
LCD_WR = 1;
delay_ms(50);
LCD_WR = 0;
//传送u16变量value低8位数据
GPIOB->ODR &= 0X00ff; //将高8位清0
GPIOB->ODR |= (value<<8)&0xff00; //传送value低8位
LCD_WR = 1;
delay_ms(50);
LCD_CS = 1;
}
/**********************************************************
写16位颜 {MOD}数据子函数
**********************************************************/
void LCD_Wirte_Data16(uint value) // color data //变量value表示16位二进制(4位16进制数)的颜 {MOD}数值
{
LCD_CS = 0;
LCD_RS = 1;
LCD_WR = 0;
//传送u16变量value高8位数据
GPIOB->ODR &= 0X00ff; //将高8位清0
GPIOB->ODR |= value&0xff00; //传送value高8位
LCD_WR = 1;
delay_ms(50);
LCD_WR = 0;
//传送u16变量value低8位数据
GPIOB->ODR &= 0X00ff; //将高8位清0
GPIOB->ODR |= (value<<8)&0xff00; //传送value低8位
LCD_WR = 1;
delay_ms(50);
LCD_CS = 1;
}
/*********************************************************
写寄存器子函数
**********************************************************/
void Reg_Write(uint reg,uint value) //写命令到寄存器 ,//reg为命令数值,//value为16位数据
{
LCD_Write(TYPE_LCD_COMMAND,reg); //写命令与数据子函数,TYPE_LCD_COMMAND为0 ,0: command //reg表示写入的command内容
LCD_Wirte_Data16(value); //写16位数据子函数
}
/**********************************************************
设置显示窗口子函数
**********************************************************/
void LCD_SetRamAddr(uint xStart, uint xEnd, uint yStart, uint yEnd) //X轴开始坐标xStart, X轴终止坐标xEnd, Y轴开始坐标 yStart, Y轴终止坐标yEnd
{
Reg_Write(0x200, xStart); //写寄存器子函数//0x200表示写入的命令值,xStart表示写入的数据
Reg_Write(0x201, yStart);
Reg_Write(0x0210, xStart);
Reg_Write(0x0212,yStart);
Reg_Write(0x211,xEnd);
Reg_Write(0x213,yEnd);
// LCD_Write(TYPE_LCD_COMMAND,0x022);
// LCD_Write(TYPE_LCD_COMMAND,0x0202); // 0x22
LCD_Write(TYPE_LCD_COMMAND,0x0202);
// delay_ms(500);
}
/**********************************************************
初始化子函数
**********************************************************/
void LCD_init(void)
{
LCD_RST=1;
delay_ms(5);
LCD_RST=0;
delay_ms(5);
LCD_RST=1;
delay_ms(5);
LCD_CS =0; //打开片选使能
Reg_Write(0x000,0x0000); delay_ms(5); //写寄存器子函数; 延时子函数
Reg_Write(0x000,0x0000); delay_ms(5);
Reg_Write(0x000,0x0000);delay_ms(5);
Reg_Write(0x000,0x0000); delay_ms(5);
delay_ms(100);
LCD_Wirte_Data16(0x0000);delay_ms(5); ////写16位数据子函数
LCD_Wirte_Data16(0x0000);delay_ms(5);
LCD_Wirte_Data16(0x0000);delay_ms(5);
LCD_Wirte_Data16(0x0000); delay_ms(5);
delay_ms(100);
Reg_Write(0x400,0x6200);delay_ms(5);
Reg_Write(0x008,0x0808); delay_ms(5);
// Reg_Write(0x010,0x0010);
Reg_Write(0x300,0x0c0c);delay_ms(5);//GAMMA
Reg_Write(0x301,0xff13); delay_ms(5);
Reg_Write(0x302,0x0f0f); delay_ms(5);
Reg_Write(0x303,0x150b); delay_ms(5);
Reg_Write(0x304,0x1020); delay_ms(5);
Reg_Write(0x305,0x0a0b); delay_ms(5);
Reg_Write(0x306,0x0003);delay_ms(5);
Reg_Write(0x307,0x0d06); delay_ms(5);
Reg_Write(0x308,0x0504); delay_ms(5);
Reg_Write(0x309,0x1030); delay_ms(5);
Reg_Write(0x010,0x001b);delay_ms(5); //60Hz
Reg_Write(0x011,0x0101);delay_ms(5);
Reg_Write(0x012,0x0000);delay_ms(5);
Reg_Write(0x013,0x0001);delay_ms(5);
Reg_Write(0x100,0x0330);delay_ms(5);//BT,AP 0x0330
Reg_Write(0x101,0x0247);delay_ms(5);//DC0,DC1,VC
Reg_Write(0x103,0x1000);delay_ms(5);//VDV //0x0f00
Reg_Write(0x280,0xbf00);delay_ms(5);//VCM
Reg_Write(0x102,0xd1b0);delay_ms(5);//VRH,VCMR,PSON,PON
delay_ms(1220);
Reg_Write(0x001,0x0100);delay_ms(5);
Reg_Write(0x002,0x0100);delay_ms(5);
Reg_Write(0x003,0x1030); delay_ms(5);
Reg_Write(0x009,0x0001);delay_ms(5);
Reg_Write(0x0C,0x0000);delay_ms(5); //MCU interface
Reg_Write(0x090,0x8000);delay_ms(5);
Reg_Write(0x00f,0x0000);delay_ms(5);
Reg_Write(0x210,0x0000);delay_ms(5);
Reg_Write(0x211,0x00ef);delay_ms(5);
Reg_Write(0x212,0x0000);delay_ms(5);
Reg_Write(0x213,0x018f); delay_ms(5);
Reg_Write(0x500,0x0000); delay_ms(5);
Reg_Write(0x501,0x0000); delay_ms(5);
Reg_Write(0x502,0x005f); delay_ms(5);
Reg_Write(0x401,0x0001); delay_ms(5);
Reg_Write(0x404,0x0000); delay_ms(5);
delay_ms(500);
Reg_Write(0x0007,0x0100);delay_ms(5);
delay_ms(1000);
Reg_Write(0x200,0x0000);delay_ms(5);
Reg_Write(0x201,0x0000);delay_ms(5);
delay_ms(500);
LCD_Write(TYPE_LCD_COMMAND,0x0202);
delay_ms(500);
}
/**********************************************************
清屏子函数
**********************************************************/
void LCD_clear(unsigned char x)
{
unsigned int com,seg;
LCD_SetRamAddr(0,239, 0,399);
delay_ms(100);
for(com=0;com<400;com++) //Y轴400点
{
for(seg=0;seg<240;seg++) //X轴240点
{
LCD_Wirte_Data16(colors[x]); //写入颜 {MOD}数据X
}
}
}
//GPIO 配置
void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能端口时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); //关闭调试端口重映射
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
}
/*******************************************************************************
* 文件名称 : 工程模板(库函数版本V3.5.0)
* 文件描述 : 11.1 lcdl2864初始化
* 编写人 : 蒋厚兵
*已经分析问题出现的可能有 :
1.PB2引脚蛸BOOT1(下载完程序后,拔去)
2.硬件上的问题:在51单片机的3.3V下测试没问题,其接线和51相同
3. STM32程序分析
A)外设时钟
B)GPIO配置
C) 引脚宏定义:和51相同
D) 赋值语句
C)时序:和51相同
F) 初始化函数:和51相同
G) 延时函数
*******************************************************************************/
#include"stm32f10x.h"
#include "rcc.h"
#include "delay.h"
#include "lcd.h"
u16 colors[]= {0xf800,0x07e0,0x001f,0xffe0,0x0000,0x07ff,0xf81f,0xffff,0x429c};
//0(red),1(green),2(blue),3(yellow),4(black),5(turquoise blue),6(violet),7(white),8(自加的)
int main()
{
u8 ii;
GPIO_Write(GPIOA, 0xffff); //
GPIO_Write(GPIOB, 0xffff); //
RCC_PLL3_Configuration();
delay_init(); //延时函数初始化
delay_ms(50); //上电,等待稳定
LCD_GPIO_Init(); //
LCD_init(); //初始化LCD
//0.屏幕初始化
for(ii=0;ii<9;ii++)
LCD_clear(ii); //从0-8变换刷新屏幕颜 {MOD}
LCD_clear(2); //停留2(blue)颜 {MOD}在屏幕
//1.刷屏测试
while(1);
}
一周热门 更多>