日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于GD32VF103 的vga显示器 和ps2键盘 驱动

發(fā)布時(shí)間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于GD32VF103 的vga显示器 和ps2键盘 驱动 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基于GD32VF103的vga和ps2鍵盤驅(qū)動(dòng)

前言

gd32vf103 是國(guó)內(nèi)一款很不錯(cuò)的riscv架構(gòu)微處理器,但是網(wǎng)上gd32vf103的應(yīng)用還比較少,這里我決定分享一下利用這個(gè)微處理器制作的vga驅(qū)動(dòng)和ps2鍵盤驅(qū)動(dòng)的調(diào)試過程和思路,主要還是用來學(xué)習(xí)定時(shí)器、spi等這些單片機(jī)常用的功能,希望能幫到有需要的人 源碼開源到了我的github上有需要自取gd32vf103 vga&ps2keyboard

PS2 鍵盤驅(qū)動(dòng)

ps2 鍵盤在幾年前還是非常多人使用,我現(xiàn)在仍然用的ps2的鍵盤鼠標(biāo) ,這里選用ps2 作為人機(jī)交互主要原因是它的接口和時(shí)序都非常簡(jiǎn)單

ps2 硬件連接

ps2 接口電路如圖
我們這里用到了四根線,大致的連接是這樣

PS2PIN -> GD32vf103PIN
4 -> 5v
3 -> GND
5(clk)->PA0
1(data) -> PA3

ps2 時(shí)序

我們這里單片機(jī)作為從機(jī)接收ps2鍵盤發(fā)來的數(shù)據(jù),所以簡(jiǎn)單來說就是在clk下降沿讀取data的電平。首先要將clk和data拉高,不然鍵盤不會(huì)發(fā)送數(shù)據(jù)。
第一位是start 0, 最后一位是stop 1,倒數(shù)第二位校驗(yàn),所以說我們要的數(shù)據(jù)就在中間data0-data7 一個(gè)移位就能讀出
我們要做的就是在clk對(duì)應(yīng)的引腳(PA0)掛上下降沿的外部中斷,然后在中斷處理函數(shù)中讀取data對(duì)應(yīng)引腳(PA3)電平,讀取的函數(shù)如下

void EXTI0_IRQHandler(void) {u8 state_now;ps2_check = 0;if (RESET != exti_interrupt_flag_get(EXTI_0)) {state_now = gpio_input_bit_get(GPIOA, PS2_DATA);if (ps2_bit_count == 11) {ps2_data_now = 0x00;if (0 == state_now) {ps2_bit_count--;}} else {if (ps2_bit_count < 11 && ps2_bit_count > 2) {ps2_data_now = (ps2_data_now >> 1);if (0 != state_now) {ps2_data_now = ps2_data_now + 0x80;}ps2_bit_count--;} else {if (ps2_bit_count == 2) {ps2_bit_count--;} else if (ps2_bit_count == 1) {ps2_bit_count = 11;u8 current_char = ps2_decode(ps2_data_now);if (current_char != 0) {set_char(current_char);}}}}}exti_interrupt_flag_clear(EXTI_0);//GPIO_BC(GPIOA) = LED_B;//printf("in handler:%d now%d\n", ps2_bit_count,state_now ); }

然后就是數(shù)據(jù)的處理了,我這里用的第二套鍵盤掃描碼,通碼如下
按鍵按下發(fā)送通碼,彈起發(fā)送斷碼,因?yàn)槲抑苓呥€有很多沒搭好,所以這里就簡(jiǎn)單處理讓檢測(cè)到f0后接收到的碼作為當(dāng)前按鍵,emmm確實(shí)這里目前沒做其他的比如shift之類的,不過也很簡(jiǎn)單,隔段時(shí)間來填這個(gè)坑吧。

vga驅(qū)動(dòng)

由于單片機(jī)的算力有限,為了還能干些其他事情 ,我們這里使用單色 分辨率是800* 600@56Hz ,同樣考慮到這只是用來刷字符的卡 實(shí)際分辨率是600* 300

硬件接口

我們用的15針vga 大致連接如下

VGAPIN -> GD32VF103
HSYNC ->PB0
VSYNC -> PB6
GREEN->PA7


red和blue就直接接地

vga 時(shí)序以及驅(qū)動(dòng)實(shí)現(xiàn)

具體單片機(jī)實(shí)現(xiàn)推薦去看看國(guó)外這個(gè)大神的,他是利用stm32f1完成,我在實(shí)現(xiàn)中也參照了他的一些思路。有關(guān)vga時(shí)序也是百度一大把這里就先不多介紹
stm32f1 vga驅(qū)動(dòng)

我使用TIMER2CH2 作為行同步信號(hào) 通道三作為計(jì)算了消影的后的時(shí)間,即開始刷像素點(diǎn)的信號(hào)
在timer2中斷處理函數(shù)中計(jì)算行數(shù)來進(jìn)行場(chǎng)同步,這里更好的是利用定時(shí)器的主從模式讓timer2來觸發(fā)timer3,我為了節(jié)約定時(shí)器采用的在中斷中記時(shí)并產(chǎn)生場(chǎng)同步信號(hào),實(shí)測(cè)效果也不錯(cuò),大致的初始化這樣

void vga_timer_config(void) {timer_oc_parameter_struct timer_ocinitpara;timer_parameter_struct timer_initpara;rcu_periph_clock_enable(RCU_TIMER2);//rcu_periph_clock_enable(RCU_TIMER3);timer_deinit(TIMER2);timer_struct_para_init(&timer_initpara);timer_initpara.prescaler = 0;timer_initpara.alignedmode = TIMER_COUNTER_EDGE;timer_initpara.counterdirection = TIMER_COUNTER_UP;timer_initpara.period = 3072;timer_initpara.clockdivision = TIMER_CKDIV_DIV1;timer_initpara.repetitioncounter = 0;timer_init(TIMER2, &timer_initpara);timer_channel_output_struct_para_init(&timer_ocinitpara);timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;timer_channel_output_config(TIMER2, TIMER_CH_2, &timer_ocinitpara);timer_channel_output_config(TIMER2, TIMER_CH_3, &timer_ocinitpara);timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_2, 216);timer_channel_output_mode_config(TIMER2, TIMER_CH_2,TIMER_OC_MODE_PWM1);timer_channel_output_shadow_config(TIMER2, TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_3, 512);timer_channel_output_mode_config(TIMER2, TIMER_CH_3,TIMER_OC_MODE_PWM1);timer_channel_output_shadow_config(TIMER2, TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);//timer_auto_reload_shadow_enable(TIMER2);//timer_master_slave_mode_config(TIMER3, TIMER_MASTER_SLAVE_MODE_ENABLE);timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH2);timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH3);timer_interrupt_enable(TIMER2,TIMER_INT_CH2 | TIMER_INT_CH3);timer_enable(TIMER2);}

由上面的分辨率算出來我們的像素時(shí)鐘頻率應(yīng)該是36mhz,加上消影時(shí)間就得到了定時(shí)器的分頻和具體的pulse

疫情在家條件有限,沒有示波器和邏輯分析儀

我們刷像素點(diǎn)使用的是spi-dma功能,即dma自動(dòng)加載像素點(diǎn)中數(shù)據(jù)到spi緩沖區(qū)發(fā)送,由于分頻限制我們做的4分頻,即時(shí)鐘頻率是27mhz 同時(shí)將每行數(shù)據(jù)刷兩次。即我們實(shí)際的分辨率是600* 300,不高,但是單片機(jī)來說足夠了,這里注意重新轉(zhuǎn)載新的一行時(shí)要先將dma失能,然后再在開始傳輸時(shí)使能dma通道

具體實(shí)現(xiàn)還是直接看我GitHub代碼吧 ,這里放幾張成功實(shí)現(xiàn)的圖

這是滿屏綠色的


由于家中條件有限,連接只有杜邦線面包板,面包板寄生電容和線上干擾很大,所以說顯示也有點(diǎn)丑陋,等打板后再繼續(xù)吧



歡迎大家來交流 郵箱 :chen.yuheng@nexuslink.cn

打板出來了,很尷尬的是定義的按鍵在boot上,插上去沒法dfu燒錄。。。



可以多個(gè)大小字體切換,改變填充方式后也更漂亮了。同時(shí)移植了mathbasic解釋器上去
tiny-math-basic解釋器

總結(jié)

以上是生活随笔為你收集整理的基于GD32VF103 的vga显示器 和ps2键盘 驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。