2017年10月8日 星期日

[C] 大樂透開獎

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
    int lot[49], choose[7], min = 1, max = 49, num = 7;
    int max_dim = max-min+1, choice, i;
   
    for(i=0; i<max_dim; i++){
        lot[i] = i+min;
    }

    srand((unsigned)time(NULL));
   
    for(i=0; i<num; i++){
        choice = rand()%max_dim;
        choose[i] = lot[choice];
        lot[choice] = lot[max_dim-1];
        max_dim--;
    }
   
    printf("\n 本期大樂透 電腦選號 號碼如下:\n\n");
   
    for(i=0; i<num-1; i++){
        printf(" %d", choose[i]);
    }
 
    printf("\n\n 特別號: %d \n\n\n", choose[num-1]);  
 
    return 0;
} 

[C] 綜合所得稅試算

/*
 
說明
 
請根據綜合所得稅速算公試表,求出使用者輸入綜合所得淨額後,印出稅率、稅金、累進差額還有今年應納稅額。
 
Input Format
 
今年所得
 
Output Format
 
所得淨額:
稅額:
稅金:
累進差額:
今年應繳:
 
Sample Input
 
1230000
 
Sample Output
 
income 1230000
tax rate 21%
tax 258300
discount 105100
taxpay 153200
 
*/
 
#include <stdio.h>
 
int main()
{
    int income, discount;
    double taxrate;
 
    scanf("%d", &income);
 
    if(income>=0 && income<=370000){
        taxrate = 0.06;
        discount = 0;
    }
 
    else if(income>370000 && income<=990000){
        taxrate = 0.13;
        discount = 25900;
    }
 
    else if(income>990000 && income<=1980000){
        taxrate = 0.21;
        discount = 105100;
    }
 
    else if(income>1980000 && income<=3720000){
        taxrate = 0.3;
        discount = 283300;
    }
 
    else if(income>3720000){
        taxrate = 0.4;
        discount = 655300;
    }
 
    else{
        printf("input error\n");
    }
 
    printf("income %d\n", income);
    printf("tax rate %.0f%%\n", taxrate*100);
    printf("tax %.0f\n", income*taxrate);
    printf("discount %d\n", discount);
    printf("taxpay %.0f\n", income*taxrate-discount);
 
    return 0;
}

[C] 猜數字遊戲

/*
 
說明
 
猜數字遊戲
讓系統隨機生成一數字介於1到5之間
使用者輸入一數字猜此數字是什麼
猜對的話輸出”猜對了”
猜錯則反之輸出”猜錯了”
 
Input Format
 
猜的數字1-5
 
Output Format
 
猜對的話輸出”你猜對了 答案正是 x”
猜錯則反之輸出”猜錯了了喔 其實是 x”
 
Sample Input
 
3
 
Sample Output
 
bingo answer is 3
 
Sample Input
 
3
 
Sample Output
 
wrong answer, answer is 5
 
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main()
{
    int guess, keyin;
    srand((unsigned)time(NULL));
    guess = rand()%5+1;
   
    scanf("%d", &keyin);
   
    if(guess == keyin)
        printf("bingo answer is %d\n", guess);
       
    else
        printf("wrong answer, answer is %d\n", guess);
       
    return 0;
}

2017年9月1日 星期五

Raspberry Pi 設定鏡像站(/etc/apt/sources.list)

更新 /etc/apt/sources.list 的台灣 Mirror




Q: 什麼是 Mirror ?


Raspbian 套件庫的更新來源,中文稱『鏡射站』。RPI成功開啟後,預設的鏡像站在國外,連線速度會受到影響,若不設定我們的 Mirror 來源,系統則自動幫我們依回應速度決定要連線的鏡像站,所以我們必須加入國內的 Mirror 來源,更新套件清單與更新套件、安裝套件等的網路下載速度會較快。

完整 mirror list : https://www.raspbian.org/RaspbianMirrors (請選擇台灣的)



       sudo nano /etc/apt/sources.list



deb http://free.nchc.org.tw/raspbian/raspbian stretch main contrib non-free rpi
     ( dpkg格式套件庫 ) ( 伺服器的位址及使用協定 ) ( 發行版本 ) ( 組別  )


最後更新套件清單即可,指令如下:



sudo apt-get update



如果沒有出 error,那我們就可以使用國內的鏡像站去下載安裝套件了

Raspberry Pi 初始設定

Raspberry Pi 第一次開機的時候,需要做初始化的設定,畫面如下圖:





Expand Filesystem:將SD卡除了開機磁區的剩餘空間作格式化,讓使用者可以運用

Change User Password:變更使用者的密碼,這裡的使用者是RPI的預設使用者 "pi" 不是 root

Enable Boot to Desktop:是否要在開機的時候直接進入 X 視窗模式

Internationalisation Options:這個裡面有三項設定,分別為語系,時區,還有鍵盤的設定

   Change Locale > en_GB.Utf-8 拿掉,選擇 en_US.Utf-8
            > 中文的部分選擇 zh_TW.UTF-8即可 (不過很少用到)

   Change Timezone > Asia > Taipei

   Change Keybord Layout > 選擇自己鍵盤的型號(不知道就選Generic 105-key (Intl) PC)
                                              > Other > English (US) > English (US) > NO AltGr key
                                              > No compose key (歐系鍵盤才有)
                   > 接下來會出現下圖的畫面,看你要不要留下 X 視窗
                                                      直接跳出的快捷鍵







Enable Camera:開啟 Camera 的功能,這個地方等要用再打開就好

Add to Rastrack:加入 Rastrack 的大家族 (看個人喜好)

Overclock:超頻功能( 如果板子的散熱做得好的話可以試看看 )

Advanced Options:進階選項,在這個裡面有幾項比較重要的設定必須做

   Hostname > 更改主機名稱,預設都是 raspberry pi 不修改的話難免會跟別人衝到
   
   Memory Split > 分記憶體給硬體加速,如果只使用文字介面的話給最低就好了
                              > 如果是要在 X 視窗跑軟體,建議給到 128 或 256
   
   SSH > 這個打開之後才能在 Win 使用 putty 連線到 RPI 


最後點選 Finish ,然後重開機設定就會生效了,如果之後還需要修改設定的話,請下
   
   sudo raspi-config  就可以進入設定畫面了

Raspberry Pi 修改解析度

由於RPI的螢幕輸出是HDMI的解析度

所以我們使用轉VGA的螢幕通常無法正常顯示

首先將植入系統的SD卡插回電腦,然後開啟唯一可以讀的到"X"槽

裡面會看到一個 config.txt 的檔案,如下圖所示:




接下來使用 Word Pad 將它打開 (使用記事本格式會跳掉)

修改以下內容:

# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=2
hdmi_mode=16

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
hdmi_drive=2


參數定義:

hdmi_group:用於指定要使用 CEA 或 DMT 的格式去設定解析度
hdmi_mode:使用 1024x768 且為 60 Hz 的解析度 
hdmi_drive:設定要驅動 DVI (1) 或 HDMI (2) 

Raspberry Pi 植入 raspbian 系統

首先我們需要準備以下物品:

     Raspberry Pi 主板
        SD卡(8G/16G/32G皆可)
        HDMI轉VGA轉接頭
        網路線
        USB鍵盤

接下來到下方網站下載我們要植入的映像檔:


https://www.raspberrypi.org/downloads/raspbian/


再來就是要植入映像檔了,這個地方有兩種方式:
    
        1. 如果是Linux的系統請直接參考 Dr lee 's blog ,下方為連結網址:
      
            http://pominglee.blogspot.tw/2013/01/raspberry-pi-sd-card.html

        2. 如果要使用Windows植入,請先下載 win32diskimager,下載後安裝即可
            下方為連結網址:

            https://drive.google.com/open?id=1DCdd5qvzJecZHnILgKbulFcfSZMt1nup
      
        2.1 將SD卡使用讀卡機連接到你的電腦上,這時候要看好跳出來的是哪個槽
      
        2.2 開啟win32diskimager , 開啟畫面如下:   

            
            Device 的地方選取我們的SD卡顯示的"X"槽
            Image File 則選我們剛剛下載的映像檔
            最後只要Write下去等它跑完就OK了
          
※切記Device的地方要選對,不然選到C或D槽,還Write下去東西就再見了

2017年6月20日 星期二

USB Data Flow and Protocol


USB Communication


Endpoints


1. 傳輸型態(data flow types)

USB 定義了四種傳輸型態:

◎ Control Transfers控制傳輸)  
用於控制傳輸命令及狀態操作。像是設定裝置、取得裝置資   訊、發送指令到裝置等。每個USB裝置都有一個Endpoint 0USB Core就是使用他在裝置插入後進行設定。

◎ Interrupt Transfers中斷傳輸)  
與一般常見的中斷不同,需要 host 端先詢問(Polling)才會執行。用一個固定速傳輸少量資料,像是USB鍵盤和滑鼠就是屬於這種方式。

◎ Bulk Transfers批次傳輸):
用於大量資料傳輸且需要確保資料無誤(如傳給印表機或隨身碟),沒有速度限制,若傳輸失敗就會重傳以確保正確。

◎ Isochronous Transfers同時傳輸)  
同樣用於大量資料傳輸,但不確保資料是否到達。例如USB視訊裝置,使用者會期望傳輸聲音或影像的速率是穩定的,若有幾張frame遺失,沒有通過CRC(Cyclic Redundancy Checks)資料也不會重傳。

2. 資料封包


TransactionUSB資料的傳輸,大部分的傳輸包含了三種封包,封包是組成USB傳輸的最小單位。


一個 Transaction 通常由三個封包組成,但依傳輸型態而定,一個 Transaction 可能包含一個、兩個、三個封包。





3. 資料傳輸

TransactionUSB資料的傳輸,大部分的傳輸包含了三種封包 Token packet, Data packet, Handshake 或稱 Status packet )。
Transaction可能是從Host傳向Device(H->D),或是從Device傳向Host(D->H)

◎傳送方向是由Token packet中指定。

◎一般來說,目標端利用Handshake (Status packet) 來判斷本次傳輸是否成功。

  (1) Token Packet Format

   每個TransactionToken封包做起始。

   Token封包定義裝置、Endpoint數量,傳輸的方向。

   PID來識別OUTINSOFSETUP處理。

   對於OUTSETUP處理,位址與端點欄位用來選擇接收資料的端點。

   對於IN處理,位址與端點欄位用來選擇傳送資料的端點。

                                                     1. IN
                                                     2. OUT
                                                     3. SOF
                                                     4. SETUP

(2) Data Packet Format
  
low-speed裝置中,Data封包最大的資料量為8 bytes;在full-speed裝置中,Data封包最大的資料量為1023 bytes;在high-speed裝置中,Data封包最大的資料量為1024 bytes以上。
  
 Data0 Data1 是兩個基本的資料封包,使用這些資料封包以提供一個機制來確定將傳送端和接收端之間的資料切換同步(data toggle synchronization)。另外在 USB2.0 當中更增加了 Data2 MData 資料封包,用於執行高速的即時傳輸(Isochronous Transfers)
                                                  1. Data0
                                                  2. Data1
(3)HandShake Packet Format

  ACK表示資料封包沒有bit stuff或是CRC錯誤,也就是PID欄位以及Data欄位沒有出現錯誤。
  NAK表示裝置無法從主機接收資料或是無資料可以傳輸到主機。NAK也被當作流量控制的用途來使用, 表示裝置暫時無資料傳送或無法接收資料。
  STALL表示裝置無法傳送或接收資料,需要主機介入來清除延遲狀況。
  NYET表示只有在USB2.0高速設備輸出事物中使用,它表示設備本次數據成功接收,但是沒有足夠的空間來接收下一次數據。主機在下一次輸出數據時,將先使用PING命令牌包來探測設備是否有足夠的空間接收數據,一面不必要的帶寬浪費。



                                                                               1. ACK
                                                                               2. NAK
                                                                               3. STALL
                                                                               4. NYET(usb2.0)



Reference: http://wiki.csie.ncku.edu.tw/embedded/USB#usb-%E8%B3%87%E6%96%99%E9%80%A3%E7%B5%90
https://www.keil.com/pack/doc/mw/USB/html/index.html

2017年5月9日 星期二

Introduction to USB



◎ HOST是怎麼知道一個USB裝置插上來了呢?
絕對不是看VBUS訊號。
其實它是偵測D+D-,如果D+有被PULL-UP,就表示有個Full Speed 裝置插入,如果是D-PULL-UP,那就是Low Speed


   High Speed裝置其實也是先進Full Speed,然後HOST會再透過一些協定(chirp)跟這個Full Speed裝置溝通,如果成功,雙方就會進High Speed模式。如果失敗,那就維持在Full Speed。很詭異是吧?其實這就是為了向下相容的緣故,因為只有兩根線,沒辦法生出第三種辨識方式了。



※ 有幾個Controller就有幾個Root Hub



※  USB Composite Device

 USB Composite Device意思是複合式裝置,它一定有兩個以上的 Interface。






◎  ResetSuspend、跟Resume是硬體訊號。要如何偵測跟應對,請看規格書。
Suspend模式下,一般狀況下,裝置是不能吃HOST超過500uA的電。這個規定很嚴格,基本上就是叫你把整個裝置都斷電的意思。如果你的裝置沒辦法整個斷電,就不要從HOST吃電,改吃電池即可。

◎  eye-pattern(眼圖),做USB裝置一定得通過眼圖測試。要讓USB裝置進入一個叫測試模式的狀態,不然沒辦法量測。一般的USB裝置一定支援測試模式,如果沒有,那就換一家chip。然後結果不能碰到灰色六角形。