A. c語言中怎麼讀取flash內容
flash是存儲晶元的一種,通過特定的程序可以修改裡面的數據。FLASH在電子以及半導體領域內往往表示Flash Memory的意思,即平時所說的「快閃記憶體」,全名叫Flash EEPROM Memory。
Flash存儲器又稱快閃記憶體,它結合了ROM和RAM的長處,不僅具備電子可擦除可編程(EEPROM)的性能,還可以快速讀取數據(NVRAM的優勢),使數據不會因為斷電而丟失。U盤和MP3里用的就是這種存儲器。在過去的20年裡,嵌入式系統一直使用ROM(EPROM)作為它們的存儲設備,然而近年來Flash全面代替了ROM(EPROM)在嵌入式系統中的地位,用作存儲Bootloader以及操作系統或者程序代碼,或者直接當硬碟使用(U盤)。
目前Flash主要有兩種NORFlash和NANDFlash。NORFlash的讀取和我們常見的SDRAM的讀取是一樣,用戶可以直接運行裝載在NORFLASH裡面的代碼,這樣可以減少SRAM的容量從而節約了成本。NANDFlash沒有採取內存的隨機讀取技術,它的讀取是以一次讀取一塊的形式來進行的,通常是一次讀取512個位元組,採用這種技術的Flash比較廉價。用戶不能直接運行NANDFlash上的代碼,因此好多使用NANDFlash的開發板除了使用NANDFlash以外,還加上了一塊小的NORFlash來運行啟動代碼。
一般小容量的用NORFlash,因為其讀取速度快,多用來存儲操作系統等重要信息,而大容量的用NANDFLASH,最常見的NANDFLASH應用是嵌入式系統採用的DOC(Disk On Chip)和我們通常用的「閃盤」,可以在線擦除。目前市面上的FLASH主要來自Intel,AMD,Fujitsu和Mxic,而生產NANDFlash的主要廠家有Samsung,Toshiba,Micron和Hynix。片內flash還是片外flash,spi介面還是其他的介面。ARM片子不一樣,答案就不一樣。根據flash手冊,按照手冊寫驅動。
B. 在讀取PGM圖像時,無法顯示24行掃圖像像素
ppm文件是一種圖像文件,有其自己的文件格式。ppm文件由兩個部分組成:第一個部分是三行ASCII碼,這個部分決定了圖像的存儲格式以及圖像的特徵;第二個部分就是圖像的數據部分,圖像就是由這個部分組成的。
ppm的第一部分由三行ASCII碼組成
第一行是P2/P3/P6
第二行是圖像的大小,先是列像素數,後是行像素數,中間有一個空格
第三行是一個介於1和65535之間的整數,而且必須是文本的,用來表示每一個像素的一個分量用幾個比特表示。
三行之後是圖像的數據流,從左到右,從上到下。在進行圖像數據存儲的時候,需要進行數據的格式,假如需要的像素值在0~255之間,那麼在進行數據文件保存的時候,所寫入文件的值就必須是以%c的形式輸入,而且數據之間沒有明顯的分離字元,圖像處理軟體會自動地識別這些像素的值,並給予處理。
PPM->Portable PixMap
PGM->Portable GreyMap
PBM->Portable BitMap
PBM支持單色圖(1個像素位)
PGM支持灰度圖形,能夠讀PBM圖形和PGM圖形,輸出PGM圖形
PPM支持真彩色圖形,可以讀上面所有格式,輸出PPM圖形
PPM圖形文件格式包括兩個部分,頭部分和圖象數據部分。頭部分由三部分組成,這三部分由回車或換行分割,但PPM的標准中是要求空格。第一行通常是P3或P6,說明是PPM格式;第二行是圖象的寬度和高度,用ASCII來表示;最後一部分是描述像素的最大顏色組成,這里允許描述超過一個位元組(0-255)的顏色值。另外可以在上面個部分的後面用#來追加註釋,注釋行是從#到該行末
C. 哪位高手知道PGM文件格式的具體介紹啊急用!
*.PGM是AS/400上的程序,類似其它平台的所謂可執行文件。可執行文件這種叫法對AS/400來講有點別扭,400上叫目標。*.PGM是程序目標,從源程序編譯而來,可以直接運行
D. C語言中如何驗證常量'abcd'在內存中如何存放呢在gcc中,輸出『abcd』的結果是『c』
初學者很難搞懂這一點的,僅憑三言兩語是說不清的,這里的復雜性,我少說可以給你講上兩三天。不同的操作系統分配內存不同,不同的開發語言也是一樣,所以,你別想在這里一下子明白。
以c語言來說,分配內存和你的定義類型有關。輸出值是你賦值有關,好像是費話。
類型有很多種,賦值也一樣。
關鍵問題是出在賦值類型與定義類型不符,還有就是溢出(不考慮演算法邏輯錯誤);
通常研究這個是為排錯用的。
首先,要明白
一個位元組是一個byte就是8個bit,即 B
每一個byte在內存中都有自己的一個地址,由低到高,通常我們用十六進製表示。
所以,你通常會見到有這么寫的0xff 0xdd 0x3a這樣的,每一個代表佔用一個內存。
0xeeff像這樣的是佔用了兩個內存。
這樣就出現在有高地址與低地址之分,在不同的系統,語言中都可能存在不同。
int i=0xeeff
這樣,就有兩種可能 ,ee是高位,存放到高地址,ff是低位存放到低地址,
另一種是高位的ee存放到低地址里,仰慕位的ff存放到高地址里。
用以下代碼測試:
#include <stdio.h>
int main()
{
char *p,*q;
int i=0xeeff;
p=&i;
printf("add=0x%x,ch=0x%x\n",p,*p);
p++;
printf("add=0x%x,ch=0x%x\n",p,*p);
}
輸出:
add=0x000000,ch=0xeeff
add=0x000000,ch=0xff
add=0x000001,ch=0xee
真正地址不是這個,我只是表示一下。
查看內存中是什麼,通過指針來控制,設計你需要的測試代碼。
32位cpu內存地址訪問最大內存空間 32bit=0xFFFFFFFF=4G(約)
還有一些深的東西就不多說了。
你的問題中一會兒說常量,一會兒又說變數的,我還得猜的你問題。
再有,你看的書上說,我想你只是記憶吧,記的不全,你只問出一半問題來。
所以我也只能為你回答一半了。要是我把所有可能幫你設計一回,再講上講,看三五天我也寫不完了。
E. 在AVR GCC中如何使用C語言在程序空間申請常量數組就像在KEIL中使用CODE或者PCODE的功能。
GCC中把大數組存入flash區的方法大全
AVRGCC中將變數定義在flash空間的方法(大數據存儲)
(1)flash常量:
#include <avr\pgmspace.h>//須增加的頭文件
const prog_uchar FlashConst = 3; //定義uchar型的常量n定義在flash里(flash常量)
unsigned char RamVar; //定義無符號整型變數(Ram變數)
RamVar = pgm_read_byte(&FlashConst); //讀取flash常量到ram變數
(2)flash一維數據:
#include <avr\pgmspace.h>
const prog_uchar s[5] = { 1, 2, 3, 4, 5 };
unsigned char RamVar; //定義無符號整型變數(Ram變數)
RamVar = pgm_read_byte( &s[1] ); //讀取s[1]的值到RamVar, or RamVar = pgm_read_byte( s+1 );
(3)flash多維數據:
#include <avr\pgmspace.h>
const prog_uchar s[4][16] = { {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7 },
{ 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8 },
{ 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0 },
{15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13 }
};
unsigned char RamVar[4],[16]; //定義無符號整型變數(Ram變數)
register char i, j;
for(i=0; i<4; ++)
{
for(j=0; j<16; j++)
{
RamVar[i][j] = pgm_read_byte( &s[i][j] ); //讀取數組s的值到RamVar
}//end for 2
}//end for 1
(4)擴展部分
avr對ram和flash是獨立編址的,ram是按8位編址,而flash卻按16位編址,讀ram和讀flash的匯編指令也是不同的。
類似flash數據類型還有:prog_void 、prog_char 、prog_int8_t、prog_uint8_t、prog_int16_t、prog_uint16_t、prog_int32_t、prog_uint32_t等。
讀取指令pgm_read_xxx宏定義其實就是一段包括了flash讀取指令的內聯匯編代碼。函數原型為:pgm_read_byte(address_short)、pgm_read_word(address_short)、 pgm_read_dword(address_short)、pgm_read_float(address_short)。括弧中是地址值。
F. 請問PGM可否打開MDL的設計格式啊 如有同行知道請教教我啊!謝謝!
不能直接打開的,可考慮讓MDL文件先轉換為公共DXF格式,再讓PGM來讀取。
我們在上海和周邊地區銷售服裝繪圖儀。讀圖板,切割機等
你也在附近可聯系我們,可隨機器提供轉換軟體和操作培訓
聯系我 可看我名字
G. 向單片機高手求助,怎樣用C語言編寫歌曲程序和歌曲代碼需要用那些工具怎麼樣編寫的要求詳細解答。謝謝!
//絕對調試通過,AVR-GCC,mega16,帶數碼顯示,單鍵開關多功能控制
#include <avr/io.h>
#include <avr/interrupt.h>
#include <tone.h>
#include <avr/pgmspace.h>
#define uchar unsigned char
#define uint unsigned int
#define key_input PINA
#define pgm16(A) ((typeof(A))pgm_read_word(&(A)))
const unsigned char seg_code[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x7f,0x3f};
const uint music[] PROGMEM={M3,F2,M5,B1,M3,F4,M2,F4,M1,B2,L6,F2,M1,F2,MM,M1,F2,L6,F2,L5,B2, L6,F2,M1,B1,MM,M1,F2,L6,F2,M6,F2,L5,F2,M3,F2,M2,F2,MM,M2,F4,M1,F4,L6,F2,M3,F2,M2,B2,
M3,F2,MM,M3,F2,MM,M3,F2,M2,F2,M1,B2,L6,F2,M1,F2,L7,F2,L5,F2,L6,B2, L5,F2,L6,F2,MM,L6,F2,L5,F2,M6,F2,M5,F2,MM,M5,F2,M3,F2,M2,F2,MM,M2,F4,M3,F4,M3,F2,M2,F2,M1,B2,
M6,F2,H1,B1,M6,F2,H2,F2,H1,F2,MM,H1,F2,M6,F2,MM,M6,F2,M5,F2,MM,M5,F2,M3,F2,M5,B2, M6,F2,H1,B1,M6,F2,H2,F2,H1,F2,MM,H1,F2,M6,F2,M5,F2,MM,M5,F2,MM,M5,F2,M3,F2,M2,B2,
M3,B1,MM,M3,F2,M5,F2,M6,F2,M5,F2,MM,M5,F2,M3,F2,MM,M3,F2,M2,F2,MM,M2,F2,M1,F2,L6,B2, L5,F2,M5,F4,MM,M5,F4,MM,M5,F2,M6,F2,M5,F2,M3,F2,M2,F2,M3,F2,MM,M3,F2,M2,B1,L6,F2,M1,B2,
M6,F2,H1,B1,M6,F2,H2,F2,H1,B1,M6,F2,MM,M6,F2,M5,F2,MM,M5,F2,M3,F2,M5,B2, M6,F2,H1,B1,M6,F2,H2,F2,H1,B1,M6,F2,
M5,F2,MM,M5,F2,MM,M5,F2,M3,F2,M2,B2,MM, M2,F2,MM,M2,F4,M1,F4,M2,F2,M3,F2,M5,F2,MM,M5,F2,MM,M5,F2,M3,F2,M2,F2,MM,M2,F4,M3,F4,M2,F2,M1,F2,L6,B2,
L5,F2,M5,F4,MM,M4,F4,MM,M5,F2,M6,F2,M5,F2,M3,F2,M2,F2,M2,F4,M3,F4,MM,M3,F2,M2,B1,L6,F2,M1,B3,0XFF,0XFF};
//因為兩個相同的音符之間無停頓,人為插入了MM(極短暫的
volatile uint i=1;
volatile uchar timeOK=0;
uchar key_scan(void);
ISR(TIMER0_COMP_vect) //CTC模式,控制音調高低
{
OCR0=pgm16(music[i-1]);
}
ISR(TIMER1_OVF_vect) //時間溢出模式,控制節拍長短
{
i+=2;
TCNT1H=(65536-pgm16(music[i]))/256; //相當於(65536-beat[i])/256
TCNT1L=(65536-pgm16(music[i]))%256; //相當於(65536-beat[i])%256
if(pgm16(music[i])==0xff)i=1; //在音調數組的最後加一個0xff,作為終止信號
if(pgm16(music[i])==0x00)TIMSK&=(~(1<<OCIE0));
else TIMSK|=(1<<OCIE0);
}
ISR(TIMER2_OVF_vect) //時間溢出模式,用於檢測按鍵,周期10ms
{
TCNT2=100;
timeOK=1;
}
void timer0_init(void)
{
TCCR0=0x00;
TCNT0=0x00;
OCR0=pgm16(music[i-1]);
TCCR0=0x1a;
//TIMSK|=(1<<OCIE0);
}
void timer1_init(void)
{
TCCR1B=0x00;
TCNT1H=(65536-pgm16(music[i]))/256;
TCNT1L=(65536-pgm16(music[i]))%256;
TCCR1A=0x00;
TCCR1B=0x05;
//TIMSK|=(1<<TOIE1);
}
void timer2_init(void)
{
TCCR2=0x00;
TCNT2=100;
TCCR2=0x03;
TIMSK|=(1<<TOIE2);
}
void MCU_init(void)
{
DDRA=0X00;
DDRB=0X00;
DDRC=0XFF;
DDRD=0XFF;
PORTB=0X00;
PORTC=0xfe;
PORTD=0xff;
}
uchar key_scan(void) //按鈕掃描函數
{
static uchar key_state=0,key_time1=0,key_time0=0; //靜態變數,調用以後,值被保留;
uchar key_press,key_return=0;
key_press=(~key_input)&0x01; //有鍵1,無鍵0
switch(key_state) //狀態機
{
case 0: //狀態0:無按鈕按下狀態
if(key_press)key_state=1;
break;
case 1: //狀態1:檢測到有按鈕被按下
if(key_press) //按鈕仍按下,轉2
{
//TIMSK^=(1<<TOIE0);
key_state=2;
key_time1=0; //按下時間初始
}
else //按鈕已經釋放,消抖
key_state=0;
break;
case 2: //狀態2:等待釋放或等待按下時間達到長按要求
if(!key_press) //按鈕已經釋放,轉3,繼續判斷是雙按還是單按
{
key_state=3;
key_time0=0; //釋放時間初始
}
else if (++key_time1>=100) //按下時間達到1000ms,返回值2,作長按判斷,轉7等待按鈕釋放
{
key_state=8;
key_time1=0;
key_return=2;
}
break;
case 8:
if(!key_press)
{
key_state=0;
key_time1=0;
}
else if (++key_time1>=50)
{
key_return=2;
key_time1=0;
}
break;
case 3: //狀態3:雙按的第二次按鈕輸入前的等待間隙,設定100ms(經過測試,100ms為比較合適的時間間隙,即為人體普通可以雙擊的速度
if(key_press)key_state=4; //在此時間,如果有按鈕被按下,將當作釋放抖動,轉4進一步作出判斷
else if (++key_time0>4) //如果沒有按鈕被按下,則等待此100ms過去,然後轉5
{
key_state=5;
key_time0=0;
}
break;
case 4: //狀態4:第二按的消抖處理
if(key_press)key_state=2; //快速連按(被認為人手指達不到要求的速率)將被返回到2,當作第一按處理
else key_state=3; //如果第二按只出現一次,不到10ms,消抖
break;
case 5: //狀態5:第二按前等待時間到達,進入正常的第二按等待輸入狀態,第二按只允許在此時間內輸入方為有效
if(key_press)key_state=6; //此時間內有被按下,轉6,判決抖動;
else if(++key_time0>14) //無輸入,則等待輸入有效時間過去,時間滿後,判定為單按,返回值1,狀態位回到0
{
key_state=0;
key_time0=0; //雙擊間隔時間一般為100ms,能夠穩定做到第二擊完成時間總共約180~200ms(因人而異)
key_return=1; //為增加采樣成功率,可適當縮短第二按前的間隙時間,增加第二按等待輸入時間,但總時間不可短於150ms
} //小於150ms,手指將很難達到雙擊的速度要求,如果時間太長則單按判斷時間過長,按鈕不靈敏,此處180ms經測試較為合適
break;
case 6: //狀態6:第二按的抖動判斷
if(key_press) //按鈕仍有效,按下有效,返回3,雙按成立,轉7等待按鈕釋放
{
key_state=7;
key_return=3;
}
else key_state=5; //抖動消除,退回5繼續等待輸入或等待輸入有效時間過去
case 7: //按鈕釋放等待狀態,所有已按下並被識別操作目的的按鈕狀態都將轉到7等待按鈕釋放,並將所有計時初始
if(!key_press)key_state=0;
key_time1=0;
key_time0=0;
break;
}
return key_return;
}
int main(void)
{
MCU_init();
timer0_init();
timer1_init();
timer2_init();
sei();
while(1)
{
if(timeOK)
{
cli();
uchar key;
key=key_scan();
if(key>0)PORTD=seg_code[key];
switch(key)
{
case 1:
TIMSK^=((1<<OCIE0)|(1<<TOIE1)); DDRB^=(1<<DDB3); PORTC=0xfd;
break;
case 2:
//TIMSK|=((1<<OCIE0)&(1<<TOIE1));
if(i>1)i+=10;
if (i>=(sizeof(music)-20))
{
i=1;
TIMSK&=(~((1<<OCIE0)|(1<<TOIE1)));
DDRB&=~(1<<DDB3);
}
PORTC=0xf0;
break;
case 3:
TIMSK&=(~((1<<OCIE0)|(1<<TOIE1)));
i=1;
TIMSK|=((1<<OCIE0)|(1<<TOIE1));
PORTC=0xfe;
break;
default:
break;
}
timeOK=0;
sei();
}
}
}
H. c語言 強制類型轉換 (unsigned char(*)(unsigned int))(PGM) 其中PGM是一個數組 這個最終轉換成什麼類型啊
函數指針類型,該指針能指向一個函數, 該函數返回值是unsigned char, 且帶有一個unsigned int的參數。
I. C語言 類型轉換
不是有強制類型轉換嗎?
強制類型轉換 強制類型轉換
當操作數的類型不同,而且不屬於基本數據類型時,經常需要強制類型轉換,將操作數轉化為所需要的類型。強制類型轉換具有兩種形式,稱為顯式強制轉換和隱式強制類型轉換。
1、顯式強制類型轉換
顯式強制類型轉換需要使用強制類型轉換運算符,格式如下:
type(<expression>)
或
(type)<expression>
其中,type為類型描述符,如int,float等。<expression>為表達式。經強制類型轉換運算符運算後,返回一個具有type類型的數值,這種強制類型轉換操作並不改變操作數本身,運算後操作數本身未改變,例如:
int nVar=0xab65;
char cChar=char (nVar);
上述強制類型轉換的結果是將整型值0xab65的高端兩個位元組刪掉,將低端兩個位元組的內容作為char型數值賦值給變數cChar,而經過類型轉換後nVar的值並未改變。
2、隱式強制類型轉換
隱式類型轉換發生在賦值表達式和有返回值的函數調用表達式中。在賦值表達式中,如果賦值符左右兩側的操作數類型不同,則將賦值符右邊操作數強制轉換為賦值符左側的類型數值後,賦值給賦值符左側的變數。在函數調用時,如果return後面表達式的類型與函數返回值類型不同,則在返回值時將return後面表達式的數值強制轉換為函數返回值類型後,再將值返回,如:
int nVar;
double dVar=3.88;
nVar=dVar;//執行本句後,nVar的值為3,而dVar的值仍是3.88
1,若已知x,y為double類型,則表達式:x=1,y=x+3/2結果是多少啊?
因為x,y都是double型,所以執行了y=x+3/2這個語句後,會輸出小樹部分,double型默認的是小數點後幾位我忘了,你自己調試下,就會明白了!
是否可以解決您的問題?
J. c語言中:一個文件夾下有 pgm.h main.c fct.c pm.c,都編譯好的,如何一起執行這三個文件
不可能說一起「執行」這三個文件,只能有一個入口點(main函數——現在有tmain wmain等但本質都是程序開始執行的起點)
只要放在一個工程里,有適當的include關系,編譯器能鏈接上裡面的函數