define中的U/L

本文解释了C语言中UL符号的作用,它是用来标记宏定义中的长整型十进制数据。文章通过具体示例说明了如何正确使用UL,并展示了不当使用时可能遇到的编译错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

U和L是 整数文字量的后缀修饰,用于显示指明整数文字量的类型为unsigned int(U)和long int(L)。  
类似的还有浮点数文字量的后缀修饰F或f,用于指明文字量表示的是一个float,而不是默认情况下的double。
经常发现一些C语言中通过#define 定义的数据中包含有UL符号,不理解为什么,把他去掉发现也没有什么区别。
现在才明白UL是标记该宏长整型 十进制 数据,而不是字符,也不是int型数据。
C语言中默认宏中的数字是整型数据。
如下面的例子:
#define LENGTH (20UL*1024*1024)
你要输出他的话就要这样:
printf(“LENGTH is %ld/n”,LENGTH);

例如;

#include <stdio.h>

#define SECONDS_PER_YEAR  60*60*24*365UL
int main(void)
{
    unsigned long int  a = SECONDS_PER_YEAR;
    printf("a = %ld/n",a);
    return 0;
}

输出结果为 a = 31536000;

注意:不能将
#define SECONDS_PER_YEAR  60*60*24*365UL 写成
#define SECONDS_PER_YEAR  (60*60*24*365)UL在
编译GCC程序,提示这个错误 error: expected ‘,’ or ‘;’ before ‘UL’;是因为UL写在了括号外面,无法与数据进行匹配;
#ifndef __LCD_H #define __LCD_H #include "sys.h" #include "stdlib.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32F407开发板 //2.4寸/2.8寸/3.5寸/4.3寸/7寸 TFT液晶驱动 //支持驱动IC型号包括:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/ // SPFD5408/1505/B505/C505/NT35310/NT35510/SSD1963等 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2010/7/4 //版本:V4.2 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved //******************************************************************************** //V4.0 20211111 //1,去掉大部分不常用驱动IC的支持 //2,新增对ST7789驱动IC的支持 //3,优化代码结构(精简源码) //V4.1 20211208 //修改NT5510 ID读取方式,改为先发送秘钥,然后读取C500和C501,从而获取正确的ID(0X5510) //V4.2 20211222 //1,修改FSMC速度,兼容7789显示OV2640数据 //2,解决因NT5510 ID读取(发送C501指令)导致SSD1963误触发软件复位进而读取不到ID问题,加延时解决 ////////////////////////////////////////////////////////////////////////////////// //LCD重要参数集 typedef struct { u16 width; //LCD 宽度 u16 height; //LCD 高度 u16 id; //LCD ID u8 dir; //横屏还是竖屏控制:0,竖屏;1,横屏。 u16 wramcmd; //开始写gram指令 u16 setxcmd; //设置x坐标指令 u16 setycmd; //设置y坐标指令 }_lcd_dev; //LCD参数 extern _lcd_dev lcddev; //管理LCD重要参数 //LCD的画笔颜色和背景色 extern u16 POINT_COLOR;//默认红色 extern u16 BACK_COLOR; //背景颜色.默认为白色 ////////////////////////////////////////////////////////////////////////////////// //-----------------LCD端口定义---------------- #define LCD_LED PBout(15) //LCD背光 PB15 //LCD地址结构体 typedef struct { vu16 LCD_REG; vu16 LCD_RAM; } LCD_TypeDef; //使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A6作为数据命令区分线 //注意设置时STM32内部会右移一位对其! 111 1110=0X7E #define LCD_BASE ((u32)(0x6C000000 | 0x0000007E)) #define LCD ((LCD_TypeDef *) LCD_BASE) ////////////////////////////////////////////////////////////////////////////////// //扫描方向定义 #define L2R_U2D 0 //从左到右,从上到下 #define L2R_D2U 1 //从左到右,从下到上 #define R2L_U2D 2 //从右到左,从上到下 #define R2L_D2U 3 //从右到左,从下到上 #define U2D_L2R 4 //从上到下,从左到右 #define U2D_R2L 5 //从上到下,从右到左 #define D2U_L2R 6 //从下到上,从左到右 #define D2U_R2L 7 //从下到上,从右到左 #define DFT_SCAN_DIR L2R_U2D //默认的扫描方向 //画笔颜色 #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 //灰色 //GUI颜色 #define DARKBLUE 0X01CF //深蓝色 #define LIGHTBLUE 0X7D7C //浅蓝色 #define GRAYBLUE 0X5458 //灰蓝色 //以上三色为PANEL的颜色 #define LIGHTGREEN 0X841F //浅绿色 //#define LIGHTGRAY 0XEF5B //浅灰色(PANNEL) #define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色 #define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色) #define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色) void LCD_Init(void); //初始化 void LCD_DisplayOn(void); //开显示 void LCD_DisplayOff(void); //关显示 void LCD_Clear(u16 Color); //清屏 void LCD_SetCursor(u16 Xpos, u16 Ypos); //设置光标 void LCD_DrawPoint(u16 x,u16 y); //画点 void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color); //快速画点 u16 LCD_ReadPoint(u16 x,u16 y); //读点 void LCD_Draw_Circle(u16 x0,u16 y0,u8 r); //画圆 void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2); //画线 void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2); //画矩形 void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color); //填充单色 void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color); //填充指定颜色 void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode); //显示一个字符 void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size); //显示一个数字 void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode); //显示 数字 void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p); //显示一个字符串,12/16字体 void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue); u16 LCD_ReadReg(u16 LCD_Reg); void LCD_WriteRAM_Prepare(void); void LCD_WriteRAM(u16 RGB_Code); void LCD_SSD_BackLightSet(u8 pwm); //SSD1963 背光控制 void LCD_Scan_Dir(u8 dir); //设置屏扫描方向 void LCD_Display_Dir(u8 dir); //设置屏幕显示方向 void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height); //设置窗口 //LCD分辨率设置 #define SSD_HOR_RESOLUTION 800 //LCD水平分辨率 #define SSD_VER_RESOLUTION 480 //LCD垂直分辨率 //LCD驱动参数设置 #define SSD_HOR_PULSE_WIDTH 1 //水平脉宽 #define SSD_HOR_BACK_PORCH 46 //水平前廊 #define SSD_HOR_FRONT_PORCH 210 //水平后廊 #define SSD_VER_PULSE_WIDTH 1 //垂直脉宽 #define SSD_VER_BACK_PORCH 23 //垂直前廊 #define SSD_VER_FRONT_PORCH 22 //垂直前廊 //如下几个参数,自动计算 #define SSD_HT (SSD_HOR_RESOLUTION+SSD_HOR_BACK_PORCH+SSD_HOR_FRONT_PORCH) #define SSD_HPS (SSD_HOR_BACK_PORCH) #define SSD_VT (SSD_VER_RESOLUTION+SSD_VER_BACK_PORCH+SSD_VER_FRONT_PORCH) #define SSD_VPS (SSD_VER_BACK_PORCH) #endif 这是LCD头文件,请使用头文件中的函数
最新发布
06-06
<think>我们使用STM32F407的标准外设库,首先需要知道芯片唯一ID的存储地址。根据STM32F407的数据手册,96位的唯一ID存储在地址0x1FFF7A10开始的12个字节中。步骤:1.包含必要的头文件:stm32f4xx.h以及LCD的头文件(假设为lcd.h)。2.定义芯片ID的基地址。3.读取该地址的3个32位数据(共12字节)并保存到一个数组中。4.将数组中的每个字节转换为两个十六进制字符,形成一个24个字符的字符串(因为每个字节需要两个十六进制字符表示)。5.使用LCD_Init()初始化液晶屏。6.使用LCD_ShowString()函数将字符串显示在LCD屏幕上。注意:正点原子的LCD驱动中,LCD_ShowString函数的使用方式可能为:LCD_ShowString(u16x,u16y,u16width,u16height,u8size,u8*p,u16color);但根据用户描述,他提供的头文件中函数为LCD_ShowString,并且之前回答中使用了两个坐标和颜色,所以我假设他的函数原型可能是:voidLCD_ShowString(u16x,u16y,constu8*str,u16color,u16bgcolor);如果实际函数不同,需要调整。为了通用性,我将按照之前回答中的函数原型来写:LCD_ShowString(x,y,字符串,字体颜色,背景颜色)代码实现:</think> ### 使用STM32F407标准外设库读取芯片序列号并显示在LCD屏 以下是完整实现方案,包含代码和关键步骤说明: #### 1. 头文件引入与定义 ```c #include "stm32f4xx.h" #include "lcd.h" // 正点原子LCD驱动 #include <stdio.h> // 用于sprintf // STM32F407芯片序列号地址定义 #define UID_BASE 0x1FFF7A10 // 96位序列号起始地址[^1] ``` #### 2. 序列号读取函数 ```c void Read_ChipUID(uint8_t *uid) { // 读取96位序列号(12字节) *(uint32_t*)&uid[0] = *(volatile uint32_t*)(UID_BASE); // 前4字节 *(uint32_t*)&uid[4] = *(volatile uint32_t*)(UID_BASE + 4); // 中4字节 *(uint32_t*)&uid[8] = *(volatile uint32_t*)(UID_BASE + 8); // 后4字节 } ``` #### 3. 序列号格式化函数 ```c void Format_UID(uint8_t *uid, char *output) { // 转换为十六进制字符串格式 for(int i = 0; i < 12; i++) { sprintf(&output[i*2], "%02X", uid[i]); // 每个字节转两个十六进制字符 } output[24] = '\0'; // 添加字符串结束符 } ``` #### 4. 主函数实现 ```c int main(void) { // 初始化外设 SystemInit(); // 系统时钟初始化 LCD_Init(); // LCD初始化 uint8_t chipUID[12]; // 存储96位ID char uidStr[25]; // 24字符(12字节×2)+1结束符 // 读取并格式化序列号 Read_ChipUID(chipUID); Format_UID(chipUID, uidStr); // LCD显示 LCD_Clear(WHITE); // 清屏(背景色) LCD_ShowString(30, 50, "芯片序列号:", RED, WHITE); LCD_ShowString(30, 70, uidStr, BLUE, WHITE); while(1) { // 主循环 } } ``` ### 关键实现点说明 1. **序列号地址**: - STM32F407的96位序列号存储在固定地址 `0x1FFF7A10`[^1] - 通过指针直接访问内存区域读取 2. **内存访问方式**: - 使用`volatile`修饰符确保编译器不优化内存访问 - 强制类型转换访问内存地址:`*(volatile uint32_t*)(地址)` 3. **数据格式化**: - 每个字节转换为两个十六进制字符(如 `0xA1` -> "A1") - 使用`sprintf`格式化为字符串:`%02X` 确保两位数显示 4. **LCD显示适配**: - `LCD_ShowString()`坐标参数(30,50)可根据屏幕分辨率调整 - 显示颜色使用正点原子驱动定义的颜色常量(RED, BLUE等) ### 显示效果示例 ``` 芯片序列号: A1B2C3D4E5F6789012345678 ``` ### 注意事项 1. **地址验证**: - 确保使用正确的UID基地址`0x1FFF7A10` - 可通过STM32CubeProgrammer验证读取的序列号 2. **内存保护**: - 代码执行时需禁用MPU(Memory Protection Unit) - 避免在睡眠模式下读取(内存可能不可访问) 3. **数据类型**: - 96位序列号存储在12字节数组中 - 最终显示为24字符的十六进制字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值