data=*(vu16*)addr;的理解?

本文详细解释了如何使用指针来操作内存中的数据,包括如何通过指针访问不同大小的数据类型,以及如何通过寄存器地址直接操作寄存器。此外还介绍了使用volatile关键字防止编译器优化的方法。

首先addr是一个32位的整形数据(比如是0x80040000),代表的是一个地址(地址一般都是32位的),(VU16*)就是把这个整数强制转换成一个指针(这个指针还是32位的,只不过它指向的数据是16位的),这个指针指向的地址里面存了一个类型为vu16的变量x,*(vu16*)addr就是把这个x赋值给data。

 

 

再来看另一个例子(怎么样通过寄存器的地址来操作寄存器,就是给寄存器赋值,下面这句话就可以操作寄存器):

很多时候我们会看到下面的宏定义

#define   MEM_ADDR(addr)            *((volatile unsigned long  *)(addr)) 


这里的addr是一个寄存器的地址(其实地址就是一个32位的数值,比如0x80040000),要将它强制转化成一个指针(并且声明这个指针指向的内容是一个32位的long型变量)
用(unsigned long  *)(addr) 即可,这样就成了一个真正的有血有肉的地址了。
前面再加一个*号,就可以访问这个地址得到其中的变量值了。


在C语言中,unsigned char *p; 定义p为一个指向unsigned char的地址指针;而 *p=1;就是向这个指针指向的地址所存储的变量赋值为1了。
至于中间加一个volatile关键字,则指示编译器不要自作主张对此进行优化,必须每次老老实实地去直接访问这个地址!!!

转载于:https://www.cnblogs.com/jblzky/p/9342110.html

static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_addr, vu_long *dummy) { vu_long *addr; ulong errs = 0; ulong val, readback; unsigned int j; vu_long offset; vu_long test_offset; vu_long pattern; vu_long temp; vu_long anti_pattern; vu_long num_words; static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ 0x00000007, /* three adjacent bits */ 0x0000000F, /* four adjacent bits */ 0x00000005, /* two non-adjacent bits */ 0x00000015, /* three non-adjacent bits */ 0x00000055, /* four non-adjacent bits */ 0xaaaaaaaa, /* alternating 1/0 */ }; num_words = (end_addr - start_addr) / sizeof(uint32_t); LOG_I("%s:%d: buf=0x%.8lx, length = 0x%.8lx\n", __func__, __LINE__, buf, num_words); /* * Data line test: write a pattern to the first * location, write the 1's complement to a 'parking' * address (changes the state of the data bus so a * floating bus doesn't give a false OK), and then * read the value back. Note that we read it back * into a variable because the next time we read it, * it might be right (been there, tough to explain to * the quality guys why it prints a failure when the * "is" and "should be" are obviously the same in the * error message). * * Rather than exhaustively testing, we test some * patterns by shifting '1' bits through a field of * '0's and '0' bits through a field of '1's (i.e. * pattern and ~pattern). */ addr = buf; for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) { val = bitpattern[j]; LOG_I("pattern = 0x%.8lx\n", val); for (; val != 0; val <<= 1) { *addr = val; *dummy = ~val; /* clear the test data off the bus */ readback = *addr; if (readback != val) { LOG_I("FAILURE (data line): " "expected %08lx, actual %08lx\n", val, readback); errs++; } *addr = ~val; *dummy = val; readback = *addr; if (readback != ~val) { LOG_I("FAILURE (data line): " "Is %08lx, should be %08lx\n", readback, ~val); errs++; } } } /* * Based on code whose Original Author and Copyright * information follows: Copyright (c) 1998 by Michael * Barr. This software is placed into the public * domain and may be used for any purpose. However, * this notice must not be changed or removed and no * warranty is either expressed or implied by its * publication or distribution. */ /* * Address line test * * Description: Test the address bus wiring in a * memory region by performing a walking * 1's test on the relevant bits of the * address and checking for aliasing. * This test will find single-bit * address failures such as stuck-high, * stuck-low, and shorted pins. The base * address and size of the region are * selected by the caller. * * Notes: For best results, the selected base * address should have enough LSB 0's to * guarantee single address bit changes. * For example, to test a 64-Kbyte * region, select a base address on a * 64-Kbyte boundary. Also, select the * region size as a power-of-two if at * all possible. * * Returns: 0 if the test succeeds, 1 if the test fails. */ pattern = (vu_long) 0xaaaaaaaa; anti_pattern = (vu_long) 0x55555555; LOG_I("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words); /* * Write the default pattern at each of the * power-of-two offsets. */ for (offset = 1; offset < num_words; offset <<= 1) addr[offset] = pattern; /* * Check for address bits stuck high. */ test_offset = 0; addr[test_offset] = anti_pattern; for (offset = 1; offset < num_words; offset <<= 1) { temp = addr[offset]; if (temp != pattern) { LOG_I("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", start_addr + offset*sizeof(uint32_t), pattern, temp); errs++; } } addr[test_offset] = pattern; /* if watchdog enable, need feed wdt */ /* * Check for addr bits stuck low or shorted. */ for (test_offset = 1; test_offset < num_words; test_offset <<= 1) { addr[test_offset] = anti_pattern; for (offset = 1; offset < num_words; offset <<= 1) { temp = addr[offset]; if ((temp != pattern) && (offset != test_offset)) { LOG_I("\nFAILURE: Address bit stuck low or" " shorted @ 0x%.8lx: expected 0x%.8lx," " actual 0x%.8lx\n", start_addr + offset*sizeof(uint32_t), pattern, temp); errs++; } } addr[test_offset] = pattern; } /* * Description: Test the integrity of a physical * memory device by performing an * increment/decrement test over the * entire region. In the process every * storage bit in the device is tested * as a zero and a one. The base address * and the size of the region are * selected by the caller. * * Returns: 0 if the test succeeds, 1 if the test fails. */ /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { /* if watchdog enable, need feed wdt */ addr[offset] = pattern; } /* * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { /* if watchdog enable, need feed wdt */ temp = addr[offset]; if (temp != pattern) { LOG_I("\nFAILURE (read/write) @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", start_addr + offset*sizeof(uint32_t), pattern, temp); errs++; } anti_pattern = ~pattern; addr[offset] = anti_pattern; } /* * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { /* if watchdog enable, need feed wdt */ anti_pattern = ~pattern; temp = addr[offset]; if (temp != anti_pattern) { LOG_I("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", start_addr + offset*sizeof(uint32_t), anti_pattern, temp); errs++; } addr[offset] = 0; } return errs; } TEST_F(phy_mem, 001_mem_bitflip_test) { uint32_t scratch_space; ulong start, end; uint32_t *dummy = &scratch_space; uint32_t count = 0; int32_t errs = 0; PARSE_PARAS(); EXPECT_EQ(argc, 2); start = 0x100000; end = 0x160000; LOG_I("Testing bitflip %08lx ... %08lx:\n", start, end); errs = mem_test_alt((vu_long *)start, start, end, dummy); count += errs; EXPECT_EQ(errs, 0x0); errs = mem_test_bitflip((vu_long *)start, start, end); count += errs; LOG_I("Tested with %d errors.\n", count); EXPECT_EQ(errs, 0x0); } 分析这段代码的作用,以及为何在运行到第一个“*addr=val;”语句时会出现死机
11-13
* ****************************************************************************** * @file lcd.c * @author MCD Application Team * @version V1.7.0 * @date 22-April-2016 * @brief Main program body ****************************************************************************** * @attention * ****************************************************************************** */ //#include "Lcd\lcd.h" //#include "stdlib.h" //#include "string.h" //#include "usart\usart.h" //#include "delay\delay.h" //#include "touch\touch.h" #include <string.h> #include <stdio.h> #include "delay\delay.h" #include "sys\sys.h" #include "usart\usart.h" #include "iic\iic.h" #include "io\io.h" #include "tft\tft.h" #include "tempture\tempture.h" #include "Lcd\lcd.h" #include "touch\touch.h" u8 ceshi_pro[50]; u8 ipnum_pro[20]; u8 passnum_pro[20]; const u8* wifiap_ssid=(const u8*)"at+wifi_conf="; //¶ÔÍâSSIDºÅ const u8* wifiap_encryption=(const u8*)"wpawpa2_aes"; //wpa/wpa2 aes¼ÓÃÜ·½Ê½ const u8* wifiap_password=(const u8*)"12345678"; //Á¬½ÓÃÜÂë #ifdef USE_FLASH_ZK #include "flash.h" #include "fontcheck.h" #else #include "font\font.h" #endif //¹ÜÀíLCDÖØÒª²ÎÊý //ĬÈÏΪÊúÆÁ _lcd_dev lcddev; //д¼Ä´æÆ÷º¯Êý //regval:¼Ä´æÆ÷Öµ void LCD_WR_REG(vu16 regval) { LCD->LCD_REG=regval;//дÈëҪдµÄ¼Ä´æÆ÷ÐòºÅ } //дLCDÊý¾Ý //data:ҪдÈëµÄÖµ void LCD_WR_DATA(vu16 data) { LCD->LCD_RAM=data; } //¶ÁLCDÊý¾Ý //·µ»ØÖµ:¶Áµ½µÄÖµ u16 LCD_RD_DATA(void) { vu16 ram; //·ÀÖ¹±»ÓÅ»¯ ram=LCD->LCD_RAM; return ram; } //д¼Ä´æÆ÷ //LCD_Reg:¼Ä´æÆ÷µØÖ· //LCD_RegValue:ҪдÈëµÄÊý¾Ý void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue) { LCD->LCD_REG = LCD_Reg; //дÈëҪдµÄ¼Ä´æÆ÷ÐòºÅ LCD->LCD_RAM = LCD_RegValue;//дÈëÊý¾Ý } //¶Á¼Ä´æÆ÷ //LCD_Reg:¼Ä´æÆ÷µØÖ· //·µ»ØÖµ:¶Áµ½µÄÊý¾Ý u16 LCD_ReadReg(u16 LCD_Reg) { LCD_WR_REG(LCD_Reg); //дÈëÒª¶ÁµÄ¼Ä´æÆ÷ÐòºÅ // delay_us(5); return LCD_RD_DATA(); //·µ»Ø¶Áµ½µÄÖµ } ////¿ªÊ¼Ð´GRAM //void LCD_WriteRAM_Prepare(void) //{ // LCD->LCD_REG=lcddev.wramcmd; //} //LCD¿ªÆôÏÔʾ void LCD_DisplayOn(void) { LCD_WR_REG(0X29); //¿ªÆôÏÔʾ } //LCD¹Ø±ÕÏÔʾ void LCD_DisplayOff(void) { LCD_WR_REG(0X28); //¹Ø±ÕÏÔʾ } //LCD·´É«ÏÔʾ void LCD_Inversion(void) { LCD_WR_REG(0x21); //·´×ªÑÕÉ« } //É趨LCD ÏñËØÉ¨Ãè·½Ïò,ĬÈÏ void LCD_Scan_Dir(u8 dir) { u16 regval=0x08;//ÑÕÉ« 08£ºBRG 00£ºRGB u16 dirreg=0; switch(dir) { case L2R_U2D://´Ó×óµ½ÓÒ,´ÓÉϵ½Ï regval|=(0<<7)|(0<<6)|(0<<5); break; } dirreg=0X36; LCD_WriteReg(dirreg,regval); } //ÉèÖÃLCDÏÔʾ·½Ïò //dir:0,ÊúÆÁ£»1,ºáÆÁ void LCD_Display_Dir(u8 dir) { lcddev.dir=0; //ÊúÆÁ lcddev.width_x=LcdPxWidth; lcddev.height_y=LcdPxHight; LCD_Scan_Dir(L2R_D2U); lcddev.setxcmd=0X2A; //ÉèÖÃ×ø±êµã¼Ä´æÆ÷ lcddev.setycmd=0X2B; //ÉèÖÃ×ø±êµã¼Ä´æÆ÷ lcddev.wramcmd=0X2C; //дÈëÃüÁî } //´ÓILI9xxx¶Á³öµÄÊý¾ÝΪGBR¸ñʽ£¬¶øÎÒÃÇдÈëµÄʱºòΪRGB¸ñʽ¡£ //ͨ¹ý¸Ãº¯Êýת»» //c:GBR¸ñʽµÄÑÕɫֵ //·µ»ØÖµ£ºRGB¸ñʽµÄÑÕɫֵ u16 LCD_BGR2RGB(u16 c) { u16 r,g,b,rgb; b=(c>>0)&0x1f; g=(c>>5)&0x3f; r=(c>>11)&0x1f; rgb=(b<<11)+(g<<5)+(r<<0); return(rgb); } /* * º¯ÊýÃû£ºlcd_init * ÃèÊö £ºLcd³õʼ»¯º¯Êý * ÊäÈë £ºdir--ÊúÆÁ0£¬ºáÆÁ1 * Êä³ö £ºlcddev.id Çý¶¯ID * µ÷Óà £ºÄÚ²¿µ÷Óà */ u16 lcd_init(u8 dir) { LCD_GPIO_Config(); usart_printf(USART1,"3333\r\n"); LCD_FSMC_Config(); delay_ms(50); // delay 50 ms usart_printf(USART1,"4444\r\n"); //¶ÁILI9486 IDµÄ¶ÁÈ¡ LCD_WR_REG(0XD3); lcddev.id=LCD_RD_DATA(); //¶Áµ½ XX lcddev.id=LCD_RD_DATA(); //¶Áµ½0X00 lcddev.id=LCD_RD_DATA(); //¶Áµ½0X94 lcddev.id<<=8; lcddev.id|=LCD_RD_DATA(); //¶Áµ½0X86 usart_printf(USART1,"ssss\r\n"); //* -----IPSÆÁµÄ²ÎÊý //LCD_WR_REG(0x21);//Display Inversion ON ·´×ªÑÕÉ« LCD_WR_REG(0x3A); LCD_WR_DATA(0x55);//Interface Pixel Format 16bit LCD_WR_REG(0xB1);LCD_WR_DATA(0xD0);LCD_WR_DATA(0x11); LCD_WR_REG(0xB6);LCD_WR_DATA(0x02);LCD_WR_DATA(0x22);// Display Function Control LCD_WR_REG(0xB7);LCD_WR_DATA(0xC6); LCD_WR_REG(0xC0);LCD_WR_DATA(0x0F);LCD_WR_DATA(0x0F);//Power control 4.5V LCD_WR_REG(0xC1);LCD_WR_DATA(0x41); LCD_WR_REG(0XC5);LCD_WR_DATA(0x00);LCD_WR_DATA(0x3A); //ûÓÐ0XF0-A ¼Ä´æÆ÷ LCD_WR_REG(0XF2);LCD_WR_DATA(0x18);LCD_WR_DATA(0xA3);LCD_WR_DATA(0x12);LCD_WR_DATA(0x02);LCD_WR_DATA(0xB2);LCD_WR_DATA(0x12);LCD_WR_DATA(0xFF);LCD_WR_DATA(0x10);LCD_WR_DATA(0x00); LCD_WR_REG(0XF7);LCD_WR_DATA(0xA9);LCD_WR_DATA(0x91);LCD_WR_DATA(0x2D);LCD_WR_DATA(0x0A);LCD_WR_DATA(0x4F); LCD_WR_REG(0XF8);LCD_WR_DATA(0x21);LCD_WR_DATA(0x04); LCD_WR_REG(0xF9); LCD_WR_DATA(0x00); LCD_WR_DATA(0x08); LCD_WR_REG(0xF4); LCD_WR_DATA(0x00); LCD_WR_DATA(0x00); LCD_WR_DATA(0x08); LCD_WR_DATA(0x91);LCD_WR_DATA(0x04); LCD_WR_REG(0xE0);LCD_WR_DATA(0x00);LCD_WR_DATA(0x0B);LCD_WR_DATA(0x10);LCD_WR_DATA(0x03);LCD_WR_DATA(0x10);LCD_WR_DATA(0x08);LCD_WR_DATA(0x33);LCD_WR_DATA(0x89);LCD_WR_DATA(0x48);LCD_WR_DATA(0x07); LCD_WR_DATA(0x0E);LCD_WR_DATA(0x0C);LCD_WR_DATA(0x28);LCD_WR_DATA(0x2D);LCD_WR_DATA(0x0F); LCD_WR_REG(0XE1);LCD_WR_DATA(0x00);LCD_WR_DATA(0x12);LCD_WR_DATA(0x17);LCD_WR_DATA(0x03);LCD_WR_DATA(0x11);LCD_WR_DATA(0x08);LCD_WR_DATA(0x37);LCD_WR_DATA(0x67);LCD_WR_DATA(0x4C); LCD_WR_DATA(0x07);LCD_WR_DATA(0x0F);LCD_WR_DATA(0x0C);LCD_WR_DATA(0x2F);LCD_WR_DATA(0x34);LCD_WR_DATA(0x0F); LCD_WR_REG(0x29); //display on LCD_Display_Dir(dir); //ĬÈÏΪÊúÆÁ0,ºáÆÁ1 LCD_WR_REG(0x11); //Exit Sleep delay_ms(120); usart_printf(USART1,"5555\r\n"); LCD_LED=1; //µãÁÁ±³¹â LCD_Clear(BLACK); return lcddev.id; } /********************************************** º¯ÊýÃû£ºLcd¿éÑ¡º¯Êý,ÈçÑ¡Ôñµã£¬xstart=xendÉèÖùâ±êλÖà ¹¦ÄÜ£ºÑ¡¶¨LcdÉÏÖ¸¶¨µÄ¾ØÐÎÇøÓò ×¢Ò⣺xStart¡¢yStart¡¢Xend¡¢YendËæ×ÅÆÁÄ»µÄÐýת¶ø¸Ä±ä£¬Î»ÖÃÊǾØÐοòµÄËĸö½Ç Èë¿Ú²ÎÊý£ºxStart x·½ÏòµÄÆðʼµã ySrart y·½ÏòµÄÆðʼµã Xend y·½ÏòµÄÖÕÖ¹µã Yend y·½ÏòµÄÖÕÖ¹µã ·µ»ØÖµ£ºÎÞ ***********************************************/ void BlockSet(u16 Xstart,u16 Xend,u16 Ystart,u16 Yend) { if(lcddev.dir>0) { LCD_WR_REG(lcddev.setxcmd); LCD_WR_DATA(Xstart>>8); LCD_WR_DATA(Xstart&0xff); LCD_WR_DATA(Xend>>8); LCD_WR_DATA(Xend&0xff); LCD_WR_REG(lcddev.setycmd); LCD_WR_DATA(Ystart>>8); LCD_WR_DATA(Ystart&0xff); LCD_WR_DATA(Yend>>8); LCD_WR_DATA(Yend&0xff); } LCD_WR_REG(lcddev.wramcmd); } /********************************************** º¯ÊýÃû£ºLcd¿éÑ¡º¯Êý ¹¦ÄÜ£ºÑ¡¶¨LcdÉÏÖ¸¶¨µÄ¾ØÐÎÇøÓò ×¢Ò⣺xStartºÍ yStartËæ×ÅÆÁÄ»µÄÐýת¶ø¸Ä±ä£¬Î»ÖÃÊǾØÐοòµÄËĸö½Ç Èë¿Ú²ÎÊý£ºxStart x·½ÏòµÄÆðʼµã ySrart y·½ÏòµÄÖÕÖ¹µã xLong Ҫѡ¶¨¾ØÐεÄx·½Ïò³¤¶È yLong Ҫѡ¶¨¾ØÐεÄy·½Ïò³¤¶È ·µ»ØÖµ£ºÎÞ ***********************************************/ void LCD_ColorBox(u16 xStart,u16 yStart,u16 xLong,u16 yLong,u16 Color) { u32 temp,xEnd,yEnd; xEnd=xStart+xLong-1; yEnd=yStart+yLong-1; if(xStart>lcddev.width_x-1) xStart=lcddev.width_x-1; if(yStart>lcddev.height_y-1) yStart=lcddev.height_y-1; if(xEnd>lcddev.width_x-1) xEnd=lcddev.width_x-1; if(yEnd>lcddev.height_y-1) yEnd=lcddev.height_y-1; BlockSet(xStart,xEnd,yStart,yEnd); for (temp=0; temp<xLong*yLong; temp++) { // LCD_WR_DATA( LCD_BGR2RGB(Color)); LCD_WR_DATA( Color); } } //ÇåÆÁº¯Êý //color:ÒªÇåÆÁµÄÌî³äÉ« void LCD_Clear(u16 color) { LCD_ColorBox(0,0,lcddev.width_x,lcddev.height_y,color); } /*******************************************ÏÔʾͼƬ¹¦Äܺ¯ÊýÇø*********************************************************************/ //nΪÏñËØ´óС>0 ,Ï൱ÓÚÕý·½ÐÎÌî³äÇø //x,y:ÏñËØµã //POINT_COLOR:´ËµãµÄÑÕÉ« void LCD_DrawPoint(u16 x,u16 y,u8 n,u16 Pen_color) { if(n>0) { LCD_ColorBox(x,y,n,n,BLUE ); } }
最新发布
12-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值