به نام خدا!

سلام دوستان عزیز

اگه مطلب وبلاگم رو دنبال کرده باشن میدونید یه پست در همین موضوع قبلا برای زبان برنامه نویسی VHDL نوشته بودم! (البته الان دارم ادامه اش میدم) الان تصمیم گرفتم برای زبان وریلوگ رو هم قرار بدم! اگه بتونیم با هر دو زبان برنامه نویسی خیلی خوب میشه! بنابراین منم تصمیم گرفتم برنامه ها رو به هر دو زبان قرار بدم! (البته نه همه برنامه ها رو اون آسون هاشو اگه قرار باشه یه مدار سخت رو تصویف کنیم باید ببینیم برای هر کدوم قسمت کدوم بهتره و با کدوم میشه راحت تر کار کرد)

خوب بریم سراغ مطلب اصلی مون!

اولین پروژه رو توی مطالب قبلی گذاشتم یه جمع کننده بود! الان برای این پست اولین کد رو برنامه ی ارسال کننده UART قرار میدم امیدوارم به دردتون بخوره!


1) برنامه ارسال کننده سریال UART Transmitter

خوب باوردریت 9600 بدون پریتی یک بیت استاپ همین!

اینم کد

module UART_TX  (CLK,SendKey,Tx);
input CLK;
input SendKey;
output Tx;
reg [15:0] Buffer = 16'b111111_1_01000010_0;
// -Idle- S- -Data- -S-   
// [Idle = NoWork   - Data = (in this code) ASCCI 'B' - Right S means Start - Left S means Stop]
reg [3:0] Number=0; // Counter of Buffer
reg [12:0] CounterPluse=0; // Counter Pulse for Creat 1/9600 time
reg StartSend; // bit Control Sending on Tx
reg EndSend=1; // bit Control Sending on Tx
reg SendKeyPrev=0; // bit Control Sending on Tx

always @ (posedge CLK)
 begin
   if (StartSend == 1 || EndSend == 0 ) begin
EndSend = 0; // Sending not Finish
   CounterPluse = CounterPluse +1;
if (CounterPluse == 5000) // 50000000MHz(Clock)/9600)Baudrate
begin
    Number = Number + 1; // Counter Buffer to Send Next Bit to TX
    CounterPluse = 0;
  if (Number == 15) // Finished Send
EndSend = 1; // Sending Finished  
end
end
 end

always @ (posedge CLK)
 begin
if (EndSend == 1) begin
 if (SendKey == 1 && SendKeyPrev==0)begin
    StartSend = 1;
 SendKeyPrev=1;
 end
else if (SendKey == 0)
 SendKeyPrev=0;
end
else
StartSend = 0;
 end
 
assign Tx = Buffer [Number];

endmodule

میتونید برنامه رو دانلود کنید!

حجم: 159 کیلوبایت


2) ارتباط SPI با FPGA در حالت Slave

خوب بالاخره با یاری خدا موفق شدم که این کد رو بنویسم! این کد رو در اصل از اینجا آوردم! ولی اگه به کدی که من نوشتم دقت کتید میبینید با اون کد فرق میکنه! و من خیلی تغییرات توش دادم حتی اولش این کد برای من کار نمیکرد که با کمی تغییرات کار کرد ولی مشکل داشت و ارسالش خیلی ناقص بود و تقریبا خراب بود! با تغییراتی که اعمال کردم دقتش خیلی بهتر شده و میتونید بهش اعتماد کنید! فقط اینو بگم که من برای تست این کد به میکروکنترلر LPC1768 متصل کردم و اونو به UART و اونو به کامپیوتر! و نتیجه رو از اونجا دیدم! بنابراین هم کد میکرو و هم کد FPGA رو اینجا قرار میدم!

module SPI_slave(clk, SCK, MOSI, MISO, SSEL, LED);
input clk;
input SCK, SSEL, MOSI;
output MISO;
output [3:0] LED;

reg LED;
reg [3:0] SCKr;  
reg [2:0] bitcnt;  // Bit Counter
reg byte_received; // has Byte received? 
wire SCK_risingedge;
wire SCK_fallingedge;
reg [7:0] byte_data_sent;
reg [7:0] byte_data_received;


always @(posedge clk) SCKr <= {SCKr[2:0], SCK};
assign SCK_risingedge = (SCKr[3:1]==3'b011);  // now we can detect SCK rising edges
assign SCK_fallingedge = (SCKr[3:1]==3'b110);  // and falling edges
always @(posedge clk)
begin
 if(~SSEL)
bitcnt <= 3'b000;
 else
 if(SCK_risingedge)
 begin
bitcnt <= bitcnt + 3'b001;
byte_data_received <= {byte_data_received[6:0], MOSI};
 end
end
always @(posedge clk) byte_received <= SSEL && SCK_risingedge && (bitcnt==3'b111);
always @(posedge clk)  if(byte_received) LED[3:0] <= byte_data_received[3:0];
always @(posedge clk)
if(SSEL)
 if(SCK_fallingedge)
if(bitcnt==3'b000)
byte_data_sent <= 8'b0101_1010 ;  // char Z
else
byte_data_sent <= {byte_data_sent[6:0], 1'b0};
assign MISO = byte_data_sent[7];  // send MSB first
endmodule

میتونید برنامه FPGA و میکرو رو از لینک زیر دانلود کنید!

البته اینم بگم که پروژه میکرو کنترلر اصلا ربطی به SPI نداره! یعنی اگه دیدید خیلی نا مفهومه چون یه سورس بود اونو ورداشتم تغییر دادم! فقط تابع main ش رو بخونید چون اون فقط مهمه!

دانلود پروژه میکرو
حجم: 2.05 مگابایت


دریافت پروژه FPGA
حجم: 3.43 مگابایت

 توجه: من خودم باد کد FPGA بالا مشکل پیدا کردم! مثلا دیگه اون چیزی رو که من میخوام نمیفرسته یعنی وسط کار قات میزنه و خراب میشه! بعد از تحقیق فهمیدم مشکل از SSEL هست که میکرو اونو کنترل مییکنه! بنابراین کلا SSEL رو بیخیال شدم! شما هم اگه همچین مشکلی داشتید کد زیر رو به جای کد بالا کپی کنید انشالله که درست میشه!

module SPI_slave(clk, SCK, MOSI, MISO, LED);
input clk;
input SCK,MOSI;
output MISO;
output [3:0] LED;

reg LED;
reg [3:0] SCKr;  
reg [2:0] bitcnt;  // Bit Counter
reg byte_received; // has Byte received? 
wire SCK_risingedge;
wire SCK_fallingedge;
reg [7:0] byte_data_sent;
reg [7:0] byte_data_received;
reg SSEL = 1;

always @(posedge clk) SCKr <= {SCKr[2:0], SCK};
assign SCK_risingedge = (SCKr[3:1]==3'b011);  // now we can detect SCK rising edges
assign SCK_fallingedge = (SCKr[3:1]==3'b110);  // and falling edges
always @(posedge clk)
begin

 if(SCK_risingedge)
 begin
bitcnt <= bitcnt + 3'b001;
byte_data_received <= {byte_data_received[6:0], MOSI};
 end
end
always @(posedge clk) byte_received <= SSEL && SCK_risingedge && (bitcnt==3'b111);
always @(posedge clk)  if(byte_received) LED[3:0] <= byte_data_received[3:0];
always @(posedge clk)
 if(SCK_fallingedge)
if(bitcnt==3'b000)
byte_data_sent <= 8'b0101_1010 ;  // char Z
else
byte_data_sent <= {byte_data_sent[6:0], 1'b0};
assign MISO = byte_data_sent[7];  // send MSB first
endmodule

البته مشکلی که کد بالا داره اینه که چون توش از SSEL استفاده نشده پس حتما SLAVE در اینجا FPGA باید روشن باشه و سپس Master شروع به کار کنه! وگرنه کاراکتر غلط نشون میده!


3) ارتباط با کارت حافظه SD

میتونید در این صفحه پروژه 6 رو ببینید!



4) به زودی انشالله..!