2024.9.6 수업날
< LED 제어2 >
이번에는 SWITCH를 입력값으로 받아서 출력인 LED를 제어해본다.
vivado 진행 순서
이때 gpio 채널에 어떤것이 해당되는지를 잘 확인해야한다.
vitis 코드에서 define 할때 채널에 따라 해당되는 것이 다르면 작동이 안되기 때문이다.
vitis 진행 순서
Mblaze_led_switch -> helloworld.c 소스코드
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#define GPIO_ID XPAR_GPIO_0_DEVICE_ID
#define LED_CHANNEL 1
#define SWITCH_CHANNEL 2
int main()
{
init_platform();
print("Start!\n\r");
XGpio_Config *cfg_ptr;
XGpio gpio_device;
u32 data;
cfg_ptr = XGpio_LookupConfig(GPIO_ID);
XGpio_CfgInitialize(&gpio_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&gpio_device, SWITCH_CHANNEL, 0xffff); // input
XGpio_SetDataDirection(&gpio_device, LED_CHANNEL, 0); // output
while(1){
data = XGpio_DiscreteRead(&gpio_device, SWITCH_CHANNEL);
XGpio_DiscreteWrite(&gpio_device, LED_CHANNEL, data);
// print("Hello World!!\n");
// MB_Sleep(1000);
}
cleanup_platform();
return 0;
}
소스코드에서 아래의 부분을 주석처리 한 후 실행하면 스위치를 올렸을 때 led가 켜지는 반응이 빨라진다.
< fnd >
이번에는 basys3의 Fnd에 숫자가 출력되게 해본다.
vivado 진행 순서
Run Connection Automation에서 All을 체크하면 모두 자동으로 연결해준다.
추가로 나중에 vivado->Diagram에서 Block의 이름을 변경하고 싶다면 아래와 같이 진행하면 된다.
vitis 진행 순서
Mblaze_fnd_app_system -> helloworld.c 소스코드(fnd에 1234로 고정)
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#define FND_ID XPAR_GPIO_0_DEVICE_ID
#define COM_CHANNEL 1
#define SEGMENT_CHANNEL 2
#define SWITCH_ID XPAR_GPIO_1_DEVICE_ID
#define SWITCH_CHANNEL 1
u32 fnd[16] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8,
0x80, 0x98, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
int main()
{
init_platform();
print("Start!\n");
XGpio_Config *cfg_ptr;
XGpio fnd_device, switch_device;
u32 data = 0;
cfg_ptr = XGpio_LookupConfig(FND_ID);
XGpio_CfgInitialize(&fnd_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&fnd_device, COM_CHANNEL, 0); // output
XGpio_SetDataDirection(&fnd_device, SEGMENT_CHANNEL, 0); // output
cfg_ptr = XGpio_LookupConfig(SWITCH_ID);
XGpio_CfgInitialize(&switch_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&switch_device, SWITCH_CHANNEL, 0xffff); // input
while(1){
// data = XGpio_DiscreteRead(&switch_device, SWITCH_CHANNEL);
data = 1234;
// data++;
// int div = 1;
// for(int i=0; i<4; i++){
// XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, ~(1<<i)); // 0b1110<<i+1
// XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/div%10]); // (data/(10^i))%10
// div *= 10;
// MB_Sleep(1);
// }
XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b1110);
XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data%10]);
MB_Sleep(1);
XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b1101);
XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/10%10]);
MB_Sleep(1);
XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b1011);
XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/100%10]);
MB_Sleep(1);
XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b0111);
XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/1000%10]);
MB_Sleep(1);
}
cleanup_platform();
return 0;
}
Mblaze_fnd_app_system -> helloworld.c 소스코드(fnd에 숫자 증가)
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#define FND_ID XPAR_GPIO_0_DEVICE_ID
#define COM_CHANNEL 1
#define SEGMENT_CHANNEL 2
#define SWITCH_ID XPAR_GPIO_1_DEVICE_ID
#define SWITCH_CHANNEL 1
u32 fnd[16] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8,
0x80, 0x98, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
int main()
{
init_platform();
print("Start!\n");
XGpio_Config *cfg_ptr;
XGpio fnd_device, switch_device;
u32 data = 0;
cfg_ptr = XGpio_LookupConfig(FND_ID);
XGpio_CfgInitialize(&fnd_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&fnd_device, COM_CHANNEL, 0); // output
XGpio_SetDataDirection(&fnd_device, SEGMENT_CHANNEL, 0); // output
cfg_ptr = XGpio_LookupConfig(SWITCH_ID);
XGpio_CfgInitialize(&switch_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&switch_device, SWITCH_CHANNEL, 0xffff); // input
while(1){
// data = XGpio_DiscreteRead(&switch_device, SWITCH_CHANNEL)
data++;
int div = 1;
for(int i=0; i<4; i++){
XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, ~(1<<i)); // 0b1110<<i+1
XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/div%10]); // (data/(10^i))%10
div *= 10;
MB_Sleep(1);
}
// XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b1110);
// XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data%10]);
// MB_Sleep(1);
//
// XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b1101);
// XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/10%10]);
// MB_Sleep(1);
//
// XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b1011);
// XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/100%10]);
// MB_Sleep(1);
//
// XGpio_DiscreteWrite(&fnd_device, COM_CHANNEL, 0b0111);
// XGpio_DiscreteWrite(&fnd_device, SEGMENT_CHANNEL, fnd[data/1000%10]);
// MB_Sleep(1);
}
cleanup_platform();
return 0;
}
Mblaze_fnd_app_system -> helloworld.c 소스코드(스위치 상태에 따라 변하는 데이터 값을 fnd에 출력하기)
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#define FND_ID XPAR_GPIO_0_DEVICE_ID
#define COM_CHANNEL 1
#define SEGMENT_CHANNEL 2
#define SWITCH_ID XPAR_GPIO_1_DEVICE_ID
#define SWITCH_CHANNEL 1
u32 fnd[16] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8,
0x80, 0x98, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
int main()
{
init_platform();
print("Start!\n");
XGpio_Config *cfg_ptr;
XGpio fnd_device, switch_device;
u32 data = 0;
cfg_ptr = XGpio_LookupConfig(FND_ID);
XGpio_CfgInitialize(&fnd_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&fnd_device, COM_CHANNEL, 0); // output
XGpio_SetDataDirection(&fnd_device, SEGMENT_CHANNEL, 0); // output
cfg_ptr = XGpio_LookupConfig(SWITCH_ID);
XGpio_CfgInitialize(&switch_device, cfg_ptr, cfg_ptr->BaseAddress);
XGpio_SetDataDirection(&switch_device, SWITCH_CHANNEL, 0xffff); // input
while(1){
data = XGpio_DiscreteRead(&switch_device, SWITCH_CHANNEL);
}
cleanup_platform();
return 0;
}
스위치 값은 2진수로 입력받고 Fnd에는 10진수로 표시되는 결과 확인
예를 들어 스위치0, 스위치1을 활성화시키면 Fnd에는 3이 표시된다.
< fnd cntr(myip) >
이번에는 기존에 만들었던 fnd 컨트롤러를 추가해서 ip를 생성한 후 diagram에 추가해본다.
vivado 진행 순서
그러면 새로운 project 창이 뜨면서 아래의 창이 새로 생긴다.
만약 Block Design project에서 아래의 창이 생기지 않는다면 Basys3 보드로 설정한 새로운 프로젝트를 만든 후에 create new ip 순서대로 진행하면 아래의 창이 생기는 것을 확인할 수 있다.
다음으로 add source를 클릭하여 전에 만들었던 fnd_cntr와 관련된 코드를 가져온다.
copy sources into IP Directory를 꼭 체크표시한다.
그러면 좌측 부분에 아래와 같이 코드가 복사된 것을 확인할 수 있다.
top 모듈인 myip_fnd_cntr도 추가로 생겼는데 아래와 같은 구조이다
myip_fnd_cntr_v1_0_S00_AXI 모듈은 slave 모듈이라고 칭한다.
fnd_4digit_cntr와 인터럽트 하기 위하여 아래와 같이 코드를 수정한다.
myip_fnd_cntr_v1_0 모듈은 top 모듈이라고 칭한다.
myip_fnd_cntr_v1_0_S00_AXI 모듈과 인스턴스하기 위해 아래와 같이 코드를 수정한다.
package ip에서 모든 항목에 초록색 체크표시가 나타나게 한 다음에 하단의 re-pacage ip를 클릭하면 된다.
Block Design으로 돌아와서 방금 만든 myip_fnd_cntr_v1 모듈을 추가해준다.
다음으로 추가한 myip_fnd_cntr에서 각 출력단을 선택하고 우클릭을하여 Make External을 선택한다.
그러면 각 출력단이 아래와 같이 만들어진다.
Block Design에서 Sources 부분에 .xdc를 추가한 다음 7 Segment Display 부분만 수정한다.
clk, reset 부분의 주석을 풀면 충돌이 날 수도 있으므로 이 부분은 그대로 주석처리를 한다.
만약 만들었던 myip를 수정하고 싶다면 해당 myip을 선택한 후 우클릭하여 Edit in IP Packager를 선택한다.
led 제어2, fnd, fnd cntr(myip) 끝!