<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>짱구핑구</title>
    <link>https://jangjy0105.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 24 May 2026 03:46:48 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>짱구핑구</managingEditor>
    <item>
      <title>VHDL 디지털시계 소스코드</title>
      <link>https://jangjy0105.tistory.com/12</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1736022204006&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity watch is
	port(
		clk			: in std_logic;
		reset			: in std_logic;
		T0, T1, T2		: in std_logic;
		fgo			: in std_logic;
		reg			: in std_logic;
		step			: in std_logic;
		sw0			: in std_logic;
		led_alarm		: out std_logic;
		FND_out1		: out std_logic_vector(7 downto 0);
		FND_out2		: out std_logic_vector(7 downto 0);
		FND_out3		: out std_logic_vector(7 downto 0);
		FND_sel1		: out std_logic_vector(1 downto 0);
		FND_sel2		: out std_logic_vector(1 downto 0);
		FND_sel3		: out std_logic_vector(1 downto 0)
	);
	function num_FND(num : integer) return std_logic_vector is
	begin
		case num is
			when 0 =&amp;gt; return &quot;11111100&quot;;
			when 1 =&amp;gt; return &quot;01100000&quot;;
			when 2 =&amp;gt; return &quot;11011010&quot;;
			when 3 =&amp;gt; return &quot;11110010&quot;;
			when 4 =&amp;gt; return &quot;01100110&quot;;
			when 5 =&amp;gt; return &quot;10110110&quot;;
			when 6 =&amp;gt; return &quot;10111110&quot;;
			when 7 =&amp;gt; return &quot;11100000&quot;;
			when 8 =&amp;gt; return &quot;11111110&quot;;
			when 9 =&amp;gt; return &quot;11110110&quot;;
			when others =&amp;gt; return &quot;00000000&quot;;
		end case;
	end function num_FND;

	function change_num(num : integer; change_mode : integer; time_plus_minus : std_logic) return integer is
	begin
		if time_plus_minus = '0' then
			case change_mode is
				when 0 =&amp;gt; return num - 1;
				when 1 =&amp;gt; return num - 60;
				when 2 =&amp;gt; return num - 3600;
				when others =&amp;gt; return num;
			end case;
		else
			case change_mode is
				when 0 =&amp;gt; return num + 1;
				when 1 =&amp;gt; return num + 60;
				when 2 =&amp;gt; return num + 3600;
				when others =&amp;gt; return num;
			end case;
		end if;
	end function change_num;
end watch;

architecture Behavioral of watch is
	signal clk_time, clk_fnd, clk_debouncing, clk_2hz	: std_logic;
	signal watch_mode				: integer range 0 to 2 := 0;
	signal change_mode				: integer range 0 to 2 := 0;
	signal time_cnt, alarm_cnt			: integer range 0 to 86400 := 0;
	signal alarm_out				: std_logic;	
	signal h0, h1, m0, m1, s0, s1			: integer range 0 to 9;
begin

	process(clk_fnd, clk_time, clk_debouncing, clk_2hz)
		variable cnt 		: integer range 0 to 999999 := 0;
		variable cnt2hz 	: integer range 0 to 249999:= 0;
		variable cnt5hz 	: integer range 0 to 199999 := 0;
		variable cnt50hz 	: integer range 0 to 9999 := 0;
	begin
		if rising_edge(clk) then		
			if cnt &amp;gt; 999999 then
				cnt := 0;
				clk_time &amp;lt;= '1';
			else
				clk_time &amp;lt;= '0';
				cnt := cnt + 1;
			end if;
			
			if cnt2hz &amp;gt; 249999 then
				cnt2hz := 0;
				clk_2hz &amp;lt;= not clk_2hz;
			else
				cnt2hz := cnt2hz + 1;
			end if;
			
			if cnt5hz &amp;gt; 199999 then
				cnt5hz := 0;
				clk_debouncing &amp;lt;= '1';
			else
				clk_debouncing &amp;lt;= '0';
				cnt5hz := cnt5hz + 1;
			end if;
			
			if cnt50hz &amp;gt;= 9999 then
				cnt50hz := 0;
				clk_fnd &amp;lt;= not clk_fnd;
			else
				cnt50hz := cnt50hz + 1;
			end if;
		end if;
	end process;
	
	process(watch_mode, change_mode)
	begin
		if rising_edge(clk) then
			if T0 = '1' then
				watch_mode &amp;lt;= 0;
				change_mode &amp;lt;= 0;
			end if;
			if T1 = '1' then
				watch_mode &amp;lt;= 1;
				change_mode &amp;lt;= 0;
			end if;
			if T2 = '1' then
				watch_mode &amp;lt;= 2;
				change_mode &amp;lt;= 0;
			end if;
			
			if clk_time = '1' then
				if fgo = '0' then
					case change_mode is
						when 0 =&amp;gt; change_mode &amp;lt;= 1;
						when 1 =&amp;gt; change_mode &amp;lt;= 2;
						when 2 =&amp;gt; change_mode &amp;lt;= 0;
					end case;
				end if;
			end if;
		end if;
	end process;
	
	process(clk_time, clk_debouncing, time_cnt, alarm_cnt)
	begin
		if rising_edge(clk) then
			if not (watch_mode = 1) then
				if clk_time = '1' then
					time_cnt &amp;lt;= time_cnt + 1;
				end if;
			end if;
			
			if watch_mode = 1 then
				if clk_debouncing = '1' then
					if reg = '0' or step = '0' then 
						time_cnt &amp;lt;= change_num(time_cnt, change_mode, reg);
					end if;
				end if;
			elsif watch_mode = 2 then
				if clk_debouncing = '1' then
					if reg = '0' or step = '0' then 
						alarm_cnt &amp;lt;= change_num(alarm_cnt, change_mode, reg);
					end if;
				end if;
			end if;
			if time_cnt &amp;gt;= 86400 or (watch_mode = 0 and reset = '0') then
				time_cnt &amp;lt;= 0;
			end if;
			if alarm_cnt &amp;gt;= 86400 or (watch_mode = 2 and reset = '0') then
				alarm_cnt &amp;lt;= 0;
			end if;
		end if;
	end process;
	
	process(alarm_out)
	begin
		if sw0 = '1' and watch_mode = 0 and time_cnt = alarm_cnt then
			alarm_out &amp;lt;= '1';
		end if;
		
		if sw0 = '0' then
			alarm_out &amp;lt;= '0';
		end if;
	end process;
	
	process(alarm_out, clk_2hz)
	begin
		if alarm_out = '1' then
			led_alarm &amp;lt;= clk_2hz;
		else
			led_alarm &amp;lt;= '0';
		end if;
	end process;
	
	process(time_cnt, s0, s1, m0, m1, h0, h1)
	begin
		if rising_edge(clk) then
			if watch_mode = 0 or watch_mode = 1 then
				s0 &amp;lt;= (time_cnt mod 60) mod 10;
				s1 &amp;lt;= (time_cnt mod 60) / 10;
				m0 &amp;lt;= ((time_cnt mod 3600) / 60) mod 10;
				m1 &amp;lt;= ((time_cnt mod 3600) / 60) / 10;
				h0 &amp;lt;= (time_cnt / 3600) mod 10;
				h1 &amp;lt;= (time_cnt / 3600) / 10;
			else
				s0 &amp;lt;= (alarm_cnt mod 60) mod 10;
				s1 &amp;lt;= (alarm_cnt mod 60) / 10;
				m0 &amp;lt;= ((alarm_cnt mod 3600) / 60) mod 10;
				m1 &amp;lt;= ((alarm_cnt mod 3600) / 60) / 10;
				h0 &amp;lt;= (alarm_cnt / 3600) mod 10;
				h1 &amp;lt;= (alarm_cnt / 3600) / 10;
			end if;
		end if;	
	end process;
	
	process(clk_fnd, h0, h1, m0, m1, s0, s1, change_mode)
	begin
		if rising_edge(clk) then
			if clk_fnd = '1' then
				FND_sel1 &amp;lt;= &quot;10&quot;;
				FND_sel2 &amp;lt;= &quot;10&quot;;
				FND_sel3 &amp;lt;= &quot;10&quot;;
				FND_out1 &amp;lt;= num_FND(h1);
				FND_out2 &amp;lt;= num_FND(m1);
				FND_out3 &amp;lt;= num_FND(s1);
			else
				FND_sel1 &amp;lt;= &quot;01&quot;;
				FND_sel2 &amp;lt;= &quot;01&quot;;
				FND_sel3 &amp;lt;= &quot;01&quot;;
				FND_out1 &amp;lt;= num_FND(h0);
				FND_out2 &amp;lt;= num_FND(m0);
				FND_out3 &amp;lt;= num_FND(s0);
			end if;
			if (not (watch_mode = 0)) and clk_2hz = '0' then
				case change_mode is
					when 0 =&amp;gt; 
						FND_sel3 &amp;lt;= &quot;11&quot;;
					when 1 =&amp;gt; 
						FND_sel2 &amp;lt;= &quot;11&quot;;
					when 2 =&amp;gt; 
						FND_sel1 &amp;lt;= &quot;11&quot;;
					when others =&amp;gt; null;
				end case;
			end if;
		end if;
	end process;

end Behavioral;​&lt;/code&gt;&lt;/pre&gt;</description>
      <category>공부</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/12</guid>
      <comments>https://jangjy0105.tistory.com/12#entry12comment</comments>
      <pubDate>Sun, 5 Jan 2025 05:25:34 +0900</pubDate>
    </item>
    <item>
      <title>토마토소스 재료 만드는 방법 보관법 및 팁</title>
      <link>https://jangjy0105.tistory.com/11</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;토마토소스는 이름 그대로 토마토를 이용해서 만드는 소스입니다. 토마토소스는 활용도가 매우 높으며 특히 파스타를 만들 때 그 활용도는 빛을 발합니다. 푸타네스카, 아마트리치아나, 비스크 파스타, 아라비아따 등 굉장히 많은 파스타에 토마토소스가 들어갑니다. 집에서 파스타를 자주 만들어 먹는 사람들에게는 필수적이라고 할 수 있습니다. 또한 토마토소스는 시판용 제품보다 직접 만든 것이 훨씬 맛있습니다. 따라서 토마토소스는 직접 만들어서 사용하는 것을 추천합니다. 토마토소스 만드는 방법을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재료&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 재료는 홀토마토 통조림 1.2kg, 양파 1개, 물 400ml, 엑스트라 버진 올리브오일, 바질입니다. 양파는 얇게 채 썰어서 준비하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만드는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가장 먼저 냄비에 올리브오일을 자작하게 둘러준 뒤 얇게 채 썬 양파를 넣고 약~중불에 볶아줍니다. 양파를 냄비에 넣은 후에는 소금으로 밑간을 해줍니다. 양파가 어느 정도 숨이 죽고 반투명해졌다면 냄비에 홀토마토를 모두 넣어줍니다. 준비해둔 물은 통조림을 헹궈 같이 넣어줍니다. 토마토소스가 어느 정도 끓기 시작하면 약간의 소금 간을 해준 뒤 가장 약한 불로 줄입니다. 이제 눌어붙지 않도록 중간중간 저어주면서 약 2시간가량 끓여줍니다. 다 끓인 뒤 불을 끄고 바질 잎을 충분히 넣어 약 10분 정도 향을 우려 줍니다. 10분 뒤 맛을 보며 마지막으로 소금 간을 해줍니다. 토마토소스는 그 자체로 완성된 요리가 아니라 조리 과정을 더 거쳐야 하기 때문에 간은 약간 싱겁게 해 주는 게 좋습니다. 이제 토마토소스가 완성되었습니다. 이렇게 만든 토마토소스는 푸드밀에 내려줍니다. 만약 푸드밀이 없다면 체에 내려서 사용해도 좋습니다. 믹서기는 씨까지 함께 갈려 맛에 좋지 않은 영향을 끼치기 때문에 사용하지 않는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;보관법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;토마토소스를 가정에서 가장 간단하게 보관할 수 있는 방법은 병조림을 만드는 것입니다. 필요한 준비물은 병조림용 병입니다. 가장 먼저 냄비에 물을 끓인 뒤 병조림용 병과 뚜껑을 끓는 물에 30초 이상 담가 살균해 줍니다. 30초 후 병과 뚜껑을 건집니다. 건져낸 병에 토마토소스를 담고 바질 잎을 한두 장 정도 넣어줍니다. 병에는 토마토소스를 가득 채우지 않습니다. 약 2cm 정도 여유 공간을 만들어주는 것이 좋습니다. 이제 뚜껑을 잘 닫아준 뒤 끓는 물에 약 40분 정도 삶아줍니다. 40분 후 불을 끄고 병조림이 물에 담긴 채로 완전히 식혀줍니다. 냄비의 물과 병조림이 차갑게 식었다면 병조림이 완성되었습니다. 이렇게 만든 병조림은 서늘하고 건조하며 햇빛이 들지 않는 곳에서 1년까지 보관이 가능합니다. 다만 뚜껑을 한번 따고 나면 보관기간이 대폭 감소하기 때문에 유의하여 주세요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;바질은 건 바질보단 생 바질을 사용해 주세요. 신선한 생 바질이 향에 있어서 월등합니다. 또한 토마토는 가능하면 산 마르자노 토마토를 사용하는 것이 좋습니다. 산 마르자노 토마토는 일반 토마토보다 감칠맛이 뛰어나 토마토소스를 만들기에 가장 적합합니다. 이외에도 DOP 인증을 받은 토마토를 사용하면 더욱 좋습니다. DOP 인증을 간단히 설명하자면 제조공정이나 재배지 등 굉장히 엄격한 기준으로 생산된 토마토라고 생각하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>요리</category>
      <category>병조림</category>
      <category>병조림 만들기</category>
      <category>토마토소스</category>
      <category>토마토소스 레시피</category>
      <category>토마토소스 보관</category>
      <category>토마토소스 재료</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/11</guid>
      <comments>https://jangjy0105.tistory.com/11#entry11comment</comments>
      <pubDate>Tue, 10 Jan 2023 00:28:35 +0900</pubDate>
    </item>
    <item>
      <title>비스크 육수 재료 준비 만드는 방법 및 주의할 점</title>
      <link>https://jangjy0105.tistory.com/10</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;비스크 육수는 갑각류의 머리와 껍질로 만드는 육수입니다. 이 육수는 리조또나 파스타 등 활용도가 높고 다른 육수들에 비해 만들기도 쉽기 때문에 한 번쯤 만들어 보는 것을 추천드립니다. 비스크 육수 만드는 방법을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재료&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;필요한 재료는 익히지 않은 새우의 머리와 껍질 1kg, 펜넬 1개, 토마토 3개, 월계수잎 1장, 통후추, 화이트와인, 올리브오일입니다. 이외에 파슬리나 마늘 등 허브를 취향껏 준비하면 됩니다. 또한 펜넬은 양파로 대체 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;만약 새우의 머리와 껍질이 아닌 생새우를 준비했다면 새우의 머리를 분리하고 껍질을 까줍니다. 새우 살도 머리, 껍질과 함께 육수에 사용해도 좋습니다. 다만 새우 살은 육수에 사용하긴 아까우니 다른 요리에 활용하는 것을 추천합니다. 바로 사용하지 않을 거라면 냉동실에 보관해도 좋습니다. 펜넬과 토마토는 적당한 크기로 썰어줍니다. 대략 3 ~ 4cm 정도면 적당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만드는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저 강불에 냄비를 데워줍니다. 냄비가 어느 정도 데워졌다면 올리브오일을 자작하게 두르고 중불로 줄인 뒤 새우의 머리와 껍질을 5분 이상 충분히 볶아줍니다. 새우의 머리와 껍질을 볶을 때에는 새우의 머리를 꾹꾹 누르면서 쥐어짜줍니다. 비스크 육수의 맛의 대부분은 새우의 머리에 있는 내장에서 나오기 때문입니다. 새우의 머리와 껍질이 완전히 익었다면 화이트와인을 넣고 '디글레이징'이라는 작업을 해줍니다. '디글레이징'이란 바닥에 음식이 눌어붙어있는 프라이팬이나 냄비에 와인, 물 등의 액체를 넣고 눌어붙은 음식을 긁어 그 풍미를 소스에 녹여내는 것입니다. 그 후 준비한 야채와 향신료를 모두 넣고 잘 볶아줍니다. 재료들이 어느 정도 물러졌다면 모든 재료가 잠길 만큼 물을 넣고 강불로 끓여줍니다. 육수가 끓는다면 떠오르는 거품을 제거한 뒤 &lt;span&gt;보글보글 &lt;/span&gt;약하게 끓는 정도(약 90도)의 불 세기를 유지해 줍니다. 이렇게 1시간가량 끓인 후 육수를 체에 걸러줍니다. 육수를 체에 거를 때에는 건더기를 꾹꾹 눌러가며 엑기스를 쥐어짜줍니다. 이제 비스크 육수가 완성되었습니다. 이렇게 만든 육수는 파스타, 리조또 등에 활용할 수 있으며 당장 쓸 것이 아니라면 소분해서 냉동실에 보관하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주의할 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;앞서 설명한 '디글레이징'이라는 작업을 하기 위해서는 냄비의 바닥에 음식이 눌어붙어야 합니다. 그러나 코팅냄비의 경우에는 코팅 때문에 음식이 눌어붙지 않아 '디글레이징'을 할 수 없고, 그만큼 육수의 풍미가 약해집니다. 따라서 새우의 머리와 껍질을 볶을 냄비는 코팅이 없는 스테인리스 냄비를 사용하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;처음에 냄비를 데울 때에는 너무 과하게 데우지 않도록 합니다. 냄비의 온도는 새우의 머리와 껍질을 넣었을 때 가볍게 지글거리는 정도면 충분합니다. 새우의 머리와 껍질을 볶을 때에도 쓴 맛이 날 수 있기 때문에 너무 강한 불에 볶지 않도록 합니다. 가볍게 지글거리는 소리가 지속적으로 들리도록 불을 조절해 줍니다.&lt;/p&gt;</description>
      <category>요리</category>
      <category>비스큐</category>
      <category>비스크</category>
      <category>비스크육수</category>
      <category>새우껍질 활용</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/10</guid>
      <comments>https://jangjy0105.tistory.com/10#entry10comment</comments>
      <pubDate>Thu, 5 Jan 2023 00:14:10 +0900</pubDate>
    </item>
    <item>
      <title>푸타네스카 재료 준비 만드는 방법 및 팁</title>
      <link>https://jangjy0105.tistory.com/9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;푸타네스카는 이탈리아 나폴리 지역에서 탄생한 파스타입니다. 토마토, 앤초비, 올리브, 케이퍼로 맛을 낸 파스타로 간단하지만 개인적으로 가장 좋아하는 파스타 중 하나입니다. 푸타네스카 만드는 방법을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재료&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;필요한 재료는 1인분 기준 스파게티 100g, 방울토마토 약 8개, 앤초비 필렛 2~3개, 블랙올리브 약 5개, 케이퍼 약 8개, 마늘 1알, 이탈리안 파슬리 1줄기, 엑스트라버진 올리브오일, 소금입니다. 스파게티는 취향껏 다른 파스타를 사용해도 무방하며, 방울토마토는 토마토소스로 대체할 수 있습니다. 또한 취향에 따라 페페론치노를 추가하여도 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저 방울토마토는 4등분 해줍니다. 케이퍼와 블랙올리브는 칼로 다져줍니다. 이때 너무 신경 써서 다질 필요는 없고 투박하게 다져줍니다. 이탈리안 파슬리는 잎과 줄기를 떼어 줄기는 따로 빼놓고 잎은 다져줍니다. 마늘은 으깨서 준비하는데, 마늘 향이 강한 걸 원한다면 다져서 준비해 줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만드는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가장 먼저 염도 1%(물 1L 당 소금 10g)의 물을 끓입니다. 물이 끓는 동안 위에서 서술한 준비 과정을 진행하면 됩니다. 물이 끓으면 파스타를 삶고, 파스타가 익는 동안 소스를 만들어줍니다. 먼저 프라이팬에 올리브오일을 둘러 마늘과 파슬리 줄기를 넣고 향을 우려 줍니다. 이때 불은 약~중불이며 페페론치노를 넣을 분들은 지금 넣으면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;어느 정도 향이 우러나왔다면 마늘과 파슬리 줄기를 건져줍니다. 마늘을 다져서 준비했다면 파슬리 줄기만 건지면 됩니다. 이제 불은 약불로 줄이고 준비해둔 블랙올리브와 케이퍼, 앤초비를 넣어서 &lt;span&gt;약 1~2분 정도 볶아줍니다.&lt;/span&gt; 이때 앤초비는 눌러서 부수면서 볶아줍니다. 볶으면서 수분이 부족하면 면수를 보충하며 볶아주는데, 앤초비에 어느 정도 간이 되어 있기 때문에 싱겁게 드시는 분들은 그냥 물을 보충하면서 볶아주면 됩니다. 어느 정도 볶아졌다면 4 등분한 방울토마토를 넣고 중간중간 면수 혹은 물을 보충하며 파스타가 익기를 기다려줍니다. 기다리면서 설거지를 해도 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;파스타는 다 익기 3~4분 전에 냄비에서 건져 프라이팬으로 옮겨 프라이팬에서 마저 익힙니다. 이때 불은 중~강불이며 수분이 적으면 간을 보면서 면수 혹은 물을 보충해 줍니다. 파스타가 다 익었다면 불을 끄고 다져놓은 파슬리와 올리브오일을 넣은 뒤 면수 혹은 물로 농도를 맞추며 만테까레를 해줍니다. 이때 파슬리는 조금 남겨놓습니다. 원하는 농도가 되었다면 접시로 옮겨 담고 남겨놓은 파슬리로 장식해주면 완성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;블랙올리브를 다질 때에는 너무 작고 일정하게 다지는 것보다는 어느 정도 크고 불규칙적으로 다져주는 게 좋습니다. 작게 썰린 올리브는 소스에 녹아들어 소스를 맛있게 하고, 크게 썰린 올리브는&amp;nbsp;한 번씩 씹었을 때의 식감과 터져 나오는 향으로 식감과 맛에 재미를 줍니다.&lt;/p&gt;</description>
      <category>요리</category>
      <category>파스타 레시피</category>
      <category>푸타네스카</category>
      <category>푸타네스카 레시피</category>
      <category>푸타네스카 만드는 방법</category>
      <category>푸타네스카 재료</category>
      <category>푸타네스카 파스타</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/9</guid>
      <comments>https://jangjy0105.tistory.com/9#entry9comment</comments>
      <pubDate>Thu, 29 Dec 2022 00:23:05 +0900</pubDate>
    </item>
    <item>
      <title>카쵸 에 페페 재료 만드는 방법 주의할 점 및 팁</title>
      <link>https://jangjy0105.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;'cacio e pepe', 직역하면 '치즈와 후추'라는 뜻입니다. 이름 그대로 치즈와 후추로 만든 로마의 정통 파스타로, 가장 기초적인 파스타입니다. 카쵸 에 페페 만드는 방법을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재료&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;필요한 재료는 1인분 기준 스파게티 100g, 페코리노 로마노 치즈 40g, 후추 약 20알, 소금입니다. 파스타는 취향에 따라 다른 것을 사용해도 무방하며, 심플한 파스타인 만큼 파스타를 직접 반죽해서 만드는 것도 좋을 것입니다. 만약 직접 만든다면 개인적으로 피치(pici)를 추천합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만드는 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저 물을 끓여줍니다. 일단은 소금을 넣지 않은 물을 끓여주세요. 물이 끓는 동안 페코리노 로마노 치즈 40g을 갈아줍니다. 물이 뜨거워졌다면 갈아놓은 페코리노 로마노 치즈에 뜨거운 물을 조금씩 부어가며 잘 섞어줍니다. 치즈가 잘 녹아 적당히 크리미해질 때까지 섞어주면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 물에 소금을 넣고 파스타를 삶아줍니다. 소금은 물 1L당 10g을 넣어주세요. 파스타를 삶는 동안에는 후추를 빻아주세요. 빻은 후추는 기름을 두르지 않은 프라이팬에 30초 정도 가볍게 볶아주는데 이는 후추의 향을 더 살리기 위함이며, 이때 불은 강불입니다. 후추를 다 볶았다면 약간의 후추만 따로 빼놓고 불은 약불로 줄인 뒤 프라이팬에 면수를 한국자 넣어줍니다. 혹시 간을 약하게 드신다면 그냥 물을 넣어주세요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;파스타는 익기 3~4분 전에 냄비에서 건져 프라이팬으로 옮긴 뒤 마저 익혀줍니다. 이때 불은 중~강불이며 물이 적으면 면수를 보충해가며 익혀줍니다. 마찬가지로 간을 약하게 드신다면 면수가 아닌 그냥 물을 보충해가며 익혀줍니다. 파스타가 다 익었다면 불을 끈 뒤 팬을 흔들어 섞으며 온도를 어느 정도 낮춘 후 미리 만들어둔 치즈를 넣어 만테까레를 해줍니다. 이때 면수 혹은 물로 농도를 조절하면 됩니다. 이제 접시에 옮겨 담고 파스타 위에 따로 빼둔 후추를 뿌려 장식해주면 완성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주의할 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가장 먼저 후추는 통후추를 사용해야 합니다. 순후추는 절대 사용하지 말고, 통후추가 없다면 사서 사용해 주세요. 또한 치즈를 뜨거운 물에 녹일 때 물의 온도는 섭씨 60도 정도가 적당합니다. 온도가 너무 높아도 안 되고 낮아도 안 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;대다수의 분들이 치즈를 갈 때 치즈 그레이터를 사용할 것입니다. 하지만 치즈 그레이터는 음식을 완성하고 나서 마무리하는 용도로 만들어졌기 때문에 뜨거운 물에 녹여 섞는 용도에는 적합하지 않으며 실제로 치즈 그레이터로 갈아낸 치즈는 물에 잘 녹이기 힘듭니다. 이를 해결하는 방법은 간단합니다. 그레이터로 한 번 갈아낸 치즈를 양손으로 비벼 고운 분말형태로 만들어 주는 것입니다. 이렇게 하면 치즈가 물에 잘 녹을 것입니다. 또한 치즈를 녹일 때에는 섭씨 60도의 온도가 적당하나 이를 정확히 측정해가며 녹이기는 상당히 번거로울 것입니다. 따라서 치즈에 끓지 않는 뜨거운 물을 아주 조금씩 추가하며 빠르게 섞어주면 적당한 농도를 잡기 용이할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;카쵸 에 페페는 간을 맞추기 번거로운 파스타입니다. 페코리노 로마노 치즈 자체가 짜기 때문입니다. 카쵸 에 페페를 어느 정도 많이 만들어 본 사람이라면 자신의 취향에 맞춰 면수와 그냥 물을 적절히 섞어가며 만들면 됩니다. 하지만 카쵸 에 페페를 많이 만들어 보지 않은 사람이라면 일단은 면수가 아닌 그냥 물을 사용하는 것이 좋습니다. 그리고 파스타를 마무리할 때 어느 정도 되직하게 마무리한 뒤, 간을 확인하며 면수 혹은 물로 농도를 조절하면 간을 조절하기 더욱 수월할 것입니다. 마지막에 면수를 추가하여 농도를 맞추었는데도 싱겁다면 페코리노 로마노 치즈를 더 갈아서 넣거나 소금을 약간 추가해주면 되겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;후추는 그라인더로 갈아도 좋지만 웬만하면 빻아서 사용하는 것을 추천하며, 너무 어느 정도 굵게 빻는 편이 좋습니다. 불규칙적인 크기로 후추를 빻았을 때 한 번씩 씹히는 큰 입자의 후추가 맛을 더욱 재미있게 해 줍니다.&lt;/p&gt;</description>
      <category>요리</category>
      <category>치즈파스타</category>
      <category>카쵸 에 페페</category>
      <category>카쵸에페페</category>
      <category>카쵸에페페 레시피</category>
      <category>카쵸에페페 만드는법</category>
      <category>파스타 레시피</category>
      <category>파스타 만드는법</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/8</guid>
      <comments>https://jangjy0105.tistory.com/8#entry8comment</comments>
      <pubDate>Thu, 22 Dec 2022 23:27:46 +0900</pubDate>
    </item>
    <item>
      <title>봉골레 파스타 재료 준비 만드는 방법 및 주의할 점</title>
      <link>https://jangjy0105.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;봉골레 파스타는 조개와 올리브오일을 이용한 파스타입니다. 한국인의 입맛에 잘 맞아 대중적으로도 인기가 많은 파스타입니다. 봉골레 파스타 만드는 방법을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재료&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;필요한 재료는 1인분 기준 링귀네 100g, 조개 약 10개, 올리브 오일, 마늘 1알, 이탈리안 파슬리 1줄기, 페페론치노 1알, 화이트와인 소량, 소금입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 재료 중 링귀네는 다른 파스타로 대체하셔도 무방하며, 조개는 바지락, 동죽, 모시조개 등 취향껏 사용하시면 됩니다. 또한 마늘, 이탈리안 파슬리, 페페론치노, 화이트와인은 있으면 좋지만 없다면 빼도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;준비&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;조개는 사용 전에 해감을 해야 합니다. 해감을 위해서 먼저 염도 약 3%(물 1L당 소금 30g)의 소금물을 만들어 줍니다. 이제 조개를 소금물이 담긴 볼에 담가 약 1시간 정도 상온에 두면 됩니다. 조개를 체에 밭쳐 소금물에 담가놓으면 불순물만 가라앉아 조개가 뱉어낸 불순물을 다시 먹지 않습니다. 조개가 담긴 볼을 덮어 어둡게 만들어도 해감이 잘 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;해감을 하는 동안 파슬리를 다져줍니다. 파슬리는 잎과 줄기를 떼어 줄기는 따로 빼놓고 잎만 칼로 다집니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;만드는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저 냄비에 염도 1%(물 1L당 소금 10g)의 물을 끓입니다. 물이 끓는 동안 조개 육수를 만들어줍니다. 먼저 프라이팬에 &lt;span&gt;적당량의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;올리브오일을 두르고 마늘 1알을 으깨서 넣고 이어서 파슬리 줄기, 부순 페페론치노를 약~중불에 살짝만 볶습니다. 강한 마늘 향을 원한다면 마늘을 으깨지 않고 다져서 넣으면 됩니다. 파슬리 줄기와 마늘이 지글거리기 시작하면 프라이팬에 조개를 넣고 소량의 화이트와인(없다면 물)을 넣고 뚜껑을 덮어줍니다. 모든 조개가 입을 벌렸다면 불을 끄고 파슬리 줄기와 마늘은 건져서 버리고, 조개는 건져서 따로 빼둡니다. 마늘을 다져서 넣었다면 건지 않아도 괜찮습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 물이 끓으면 끓는 물에 파스타를 넣고 삶아줍니다. 파스타를 삶는 동안 조개 살을 발라주시고, 시간이 남으면 설거지를 해도 좋습니다. 파스타는 다 익기 3~4분 전에 건져 조개육수가 있는 프라이팬으로 옮겨 중~강불에 마저 익혀줍니다. 이때 물이 적으면 면수(짜다면 물)를 보충해가며 익혀줍니다. 파스타가 다 익었다면 불을 끄고 발라둔 조갯살과 소량의 올리브오일을 넣은 뒤 이전 포스팅에서 설명드린 '만테까레'를 해줍니다. 짧게 설명하자면 소스를 끈적하게 하여 소스가 면에 잘 엉겨 붙게 하는 것입니다. 만테까레가 끝나면 다진 파슬리 잎을 뿌린 뒤, 마지막으로 한번 더 섞고 접시에 담으면 완성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주의할 점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;알리오올리오 파스타와 마찬가지로 미리 다져진 마늘이 아닌 사용 직전에 다진 마늘을 사용하여야 합니다. 또한 조갯살만 발라진 제품은 절대로 안됩니다. 육수 맛에 있어서 껍데기째로 있는 조개와 살만 발라진 조개는 차이가 굉장히 큽니다. 해감하는 게 조금 번거롭더라도 껍데기째로 있는 조개를 사용해 주세요. 처음 프라이팬에 조개를 넣을 때에는 볼 째로 쏟지 마시고 손으로 집어서 넣어줍니다. 볼 바닥에 깔린 물이 들어가지 않게 하기 위함입니다. 또한 탱글탱글한 조개를 위해서는 조개를 너무 많이 익히지 않는 것이 좋습니다. 오래 익힌다면 육수가 조금 진해지긴 하겠지만 드라마틱하게 진해지지 않을뿐더러 육수가 진해짐으로써 생기는 장점보다 조개가 질겨짐으로써 생기는 단점이 더 큽니다. 모든 조개가 입을 벌리면 시간을 지체하지 말고 빠르게 건져줍시다.&lt;/p&gt;</description>
      <category>요리</category>
      <category>봉골레</category>
      <category>봉골레파스타</category>
      <category>봉골레파스타 레시피</category>
      <category>파스타</category>
      <category>파스타 레시피</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/7</guid>
      <comments>https://jangjy0105.tistory.com/7#entry7comment</comments>
      <pubDate>Wed, 21 Dec 2022 11:28:57 +0900</pubDate>
    </item>
    <item>
      <title>알리오올리오 파스타 재료 만드는 방법 순서 및 주의할 점</title>
      <link>https://jangjy0105.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;'Aglio olio e peperoncino', 알리오올리오 파스타의 이탈리아어로, 직역하면 '마늘 기름 고추'라는 뜻입니다. 이름 그대로 마늘, 고추, 올리브오일을 소스로 하는 파스타입니다. 굉장히 기본적인 파스타로 만들기도 굉장히 쉬운 편입니다. 알리오 올리오 파스타 만드는 방법을 알아봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재료&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;필요한 재료는 1인분 기준 스파게티 100g, 마늘 2알, 엑스트라버진 올리브오일, 페페론치노 1알, 소금입니다. 파스타의 경우 꼭 스파게티일 필요는 없으며, 취향에 따라 고르시면 됩니다. 재료의 양 또한 취향껏 조절하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;만드는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저 냄비에 물을 끓여 파스타를 삶습니다. 물에는 소금을 넣어야 하는데, 소금은 물 양의 1/100 정도로 넣습니다. 예를 들어 물이 1L라면 소금은 10g을 넣으면 됩니다. 물이 끓는 동안 마늘을 칼로 다져줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 프라이팬에 올리브오일 적당량과 다진마늘, 부순 페페론치노를 넣은 후 약~중불에 마늘을 가볍게 볶아줍니다. 마늘이 어느 정도 볶아졌으면 불을 약불로 줄인 후 프라이팬에 면수를 넣습니다. 면수를 넣는 이유는 첫째로 프라이팬의 온도를 낮추어 마늘이 지나치게 익는 것을 방지하기 위함이고, 둘째로 소금을 넣은 면수로 소스에 간을 하기 위함이고, 셋째로 파스타에서 나온 전분의 감칠맛을 소스에 입히기 위함입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;파스타를 익히는 시간은 파스타 포장지에 표시되어 있는데, 이 시간이 되기 3~4분 전에 냄비에서 꺼내 소스가 있는 프라이팬으로 옮긴 뒤 프라이팬에서 마저 익힙니다. 프라이팬으로 옮긴 후 불은 중~강불로 하시고, 물이 적으면 면수를 보충해가며 익히시면 됩니다. 만약 소스가 짜다면 면수가 아닌 그냥 물을 보충해가며 익혀주세요. 냄비가 아닌 프라이팬에서 마무리하는 이유는 파스타의 전분을 온전히 소스에 녹아들게 하기 위함입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;파스타가 다 익었다면 불을 끈 뒤 약간의 올리브오일을 보충하고 팬을 흔들어 면과 소스를 식히면서 잘 섞어주세요. 이는 '만테까레'라고 하는데, 전분으로 하여금 오일과 물을 잘 섞이게 하여 소스를 끈적하게 하기 위한 작업입니다. 소스가 끈적하면 면에 소스가 잘 엉겨 붙어 더욱 맛있는 파스타를 먹을 수 있습니다. 이제 파스타를 접시에 옮기면 완성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;순서&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가장 먼저 냄비에 물을 끓인 후 소금을 넣습니다. 물을 끓이는 동안 마늘을 다집니다. 물이 끓었다면 파스타를 삶습니다. 파스타를 삶는 동안 프라이팬에서 마늘을 볶은 뒤 프라이팬에 면수를 넣고 파스타가 익기를 기다립니다. 기다리는 동안은 마늘을 썰었던 칼, 도마 등 사용했던 식기를 설거지합니다. 파스타가 어느 정도 익었다면 파스타를 프라이팬에 옮긴 뒤 사용할 분량의 면수를 덜어놓고, 파스타가 마저 익는 동안 냄비를 설거지합니다. 이제 파스타를 마저 익혀 마무리하면 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;요리를 빠르게 완성하기 위해서는 순서가 중요합니다. 예를 들어 마늘을 다진 후 소스를 만들고, 그 뒤에 물을 끓인다면 훨씬 오래 걸리겠죠? 요리의 순서를 잘 생각하고 남는 시간에 설거지를 하면 요리가 빠르게 완성되며, 식사가 끝난 뒤 설거지거리도 줄일 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주의할 점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;알리오올리오 파스타에 사용될 마늘은 사용 직전에 다져야 합니다. 미리 다져진 마늘보다 사용 직전에 다진 마늘을 사용하는 것이 맛과 향에 있어서 월등합니다. 마늘을 볶을 때에는 마늘에 색이 날 때까지 볶으면 안 됩니다. 마늘을 색이 날 때까지 볶는다면 마늘의 좋은 향은 모두 날아가고 쓴 맛만 남습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그냥 생각&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;한국인은 '마늘의 민족'이라고 합니다. 다른 나라에서는 향신료로만 사용하는 마늘을 생으로 먹기도 하고, 어떤 요리든 마늘이 들어갑니다. 알리오올리오 파스타 1인분에 10알 이상의 마늘이 들어가는 레시피도 찾아볼 수 있습니다. 반면 이탈리아의 알리오올리오 파스타 레시피를 찾아보면 마늘이 많아야 2알이며, 오일에 마늘향만 우려내고 마늘을 건져내는 레시피도 있습니다. 어떤 것이 더 맛있다고는 할 수 없습니다. 맛은 주관적이기 때문입니다. 다만 면, 올리브오일 등 이외 요소들의 맛은 뒷전으로 한 채 마늘의 맛만을 중시하는 파스타보다는 이외 요소들의 맛 하나하나 세세하게 신경 쓴 파스타를 음미한다면 더 맛있는 면을 고르고, 더 좋은 올리브오일을 사용할 것이며, 요리와 미식을 더 재미있게 즐길 수 있을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>요리</category>
      <category>레시피</category>
      <category>알리오올리오</category>
      <category>알리오올리오 파스타</category>
      <category>파스타</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/6</guid>
      <comments>https://jangjy0105.tistory.com/6#entry6comment</comments>
      <pubDate>Fri, 16 Dec 2022 14:21:55 +0900</pubDate>
    </item>
    <item>
      <title>Atmega128 - 장애물 피하기 게임 만들기(2)</title>
      <link>https://jangjy0105.tistory.com/5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅은 작성자가 2021년에 수강했던 마이크로프로세서 강의에 제출한 과제를 바탕으로 작성되었으며, 현재와 문법이 다를 수 있습니다. 또한 학부 수준의 지식으로 작성되었기에 틀린 부분이 존재할 가능성이 다분합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;- 회로도&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgAGt9/btrNyGAPb79/Ic44S8I0IRky1OJOlKjk30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgAGt9/btrNyGAPb79/Ic44S8I0IRky1OJOlKjk30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgAGt9/btrNyGAPb79/Ic44S8I0IRky1OJOlKjk30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgAGt9%2FbtrNyGAPb79%2FIc44S8I0IRky1OJOlKjk30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;702&quot; height=&quot;540&quot; data-origin-width=&quot;702&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 설계한 회로의 회로도이다.&lt;br /&gt;PA0, PA1, PA2에는 각각 LCD의 RS, R/W, E를 연결하였고, PA8(VCC), PA9(GND)에는 각각 LCD의 Vdd, Vss를 연결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7에는 각각 LCD의 DB0, DB1, DB2, DB3, DB4, DB5, DB6, DB7을 연결하였고 PB8(VCC), PB9(GND)에고 는 각각 LCD의 BLA, BLK를 연결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7에는 각각 FND의 A, B, C, D, E, F, G, DP를 연결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PD0에는 외부 인터럽트로 사용될 스위치와 연결하였고 PD8(VCC), PD9(GND)에는 각각 스위치 회로의 VCC, GND를 연결하였다. PE0, PE1에는 Buzzer를 연결하였다. &lt;br /&gt;PF0, PF1, PF2, PF3에는 각각 FND의 C1, C2, C3, C4를 연결하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;- 코드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1664808207679&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
 * 0528.c
 *
 * Created: 2021-05-28 오후 1:05:26
 * Author: 장재영
 */

#define F_CPU 16000000
 
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;mega128.h&amp;gt;
#include &amp;lt;delay.h&amp;gt;
 
#define CMD_WRITE   0xFC  //명령어쓰기 E=1, RW=0, RS=0
#define DATA_WRITE  0xFD  //데이터쓰기 E=1, RW=0, RS=1
#define LCD_EN      0x04  
 
int i;
int k = -1;
int count = 0;
int level = 9;
int life = 2;
unsigned char position[2] = {0xc0, 0x80};
 
unsigned char fnd_sel[4] = {0b00001000, 0b00000100, 0b00000010, 0b00000001};
unsigned char fnd_data[10] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90};
 
void LCD_cmd_write(char cmd){
    PORTA = CMD_WRITE;
    PORTB = cmd;
    PORTA = PORTA^LCD_EN;
    delay_ms(2);
}
 
void LCD_data_write(char data){
    PORTA = DATA_WRITE;
    PORTB = data;
    PORTA = PORTA^LCD_EN;
    delay_ms(2);
}
 
void LCD_wr_string(char d_line, char *lcd_str){
    LCD_cmd_write(d_line);
    while(*lcd_str != '\0'){
        LCD_data_write(*lcd_str);
        lcd_str++;
    }
}
 
void FND_score(int score){
    int temp = score;
    unsigned char fnd[4];
 
   
    for(i = 0; i &amp;lt; 4; i++){
        fnd[i] = temp%10;
        temp = temp/10;
    }
    for(i = 0; i &amp;lt; 4; i++){
        PORTC = fnd_data[fnd[i]];
        PORTF = fnd_sel[i];
        delay_ms(5);
    }
}
 
void FND_life(void){
    PORTF = fnd_sel[1];
    PORTC = fnd_data[life];
}
 
char generate_hurdle(char *line1, char *line2){
        if(rand()%level == 0 &amp;amp;&amp;amp; *(line2+15) == ' ' &amp;amp;&amp;amp; *(line2+14) == ' ' &amp;amp;&amp;amp; *(line1+14) == ' ' &amp;amp;&amp;amp; *(line1+13) == ' ') return '*'; 
        else return ' ';
}
 
char generate_life(char hurdle){
    if(rand()%200 == 0 &amp;amp;&amp;amp; life &amp;lt; 8) return '+';
    else return hurdle;
}
 
void LCD_display(char *line1, char *line2){
    LCD_wr_string(position[1] ,line1);
    LCD_wr_string(position[0] ,line2);
    LCD_wr_string(position[k%2],&quot;o&quot;);
    LCD_wr_string(position[(k+1)%2],&quot; &quot;);
}
 
void get_life(char life1, char life2){
    if((life1 == '+' &amp;amp;&amp;amp; k%2 == 1) || (life2 == '+' &amp;amp;&amp;amp; k%2 == 0)){
        life++;
        FND_life();
        for(i = 0; i &amp;lt; 5; i++){
            PORTE = 0x01;
            delay_ms(2);
            PORTE = 0x02;
            delay_ms(2);  
        }
    }    
}
 
void bump(char *line1,char *line2, int position){  
    int score;
    if(*line1 == '*' &amp;amp;&amp;amp; k%2 == position){
        life--;
        FND_life();
        for(i = 0; i &amp;lt; 250; i++){
            PORTE = 0x01;
            delay_ms(2);
            PORTE = 0x02;
            delay_ms(2);  
        } 
        k = position;
        if (life == 0){
            for(i = 0; i &amp;lt; 16; i++){
                *(line1+i) = ' ';
                *(line2+i) = ' ';
            }
            LCD_cmd_write(0x01);
            LCD_wr_string(0x80,&quot;   GAME OVER&quot;);
            score = count;
            count = 0;
            level = 9;
            life = 2;
            k = -1;
            while(k == -1){FND_score(score);} 
        }
    }    
}
 
void move_line(char *line1, char *line2){
    for(i = 0; i &amp;lt; 15; i++){
        *(line1+i) = *(line1+i+1);
        *(line2+i) = *(line2+i+1);
    }  
}
 
void level_up(){
    if(count%100 == 0 &amp;amp;&amp;amp; level != 2){
        level--;
    }
}
 
interrupt [EXT_INT0] void ext_int0_isr(void){
    #asm(&quot;cli&quot;);   //interrupt disable
    k++;
    #asm(&quot;sei&quot;); //interrupt enable
} 
 
void init_LCD(void){
    delay_ms(15);        //15msec 이상 시간지연
    LCD_cmd_write(0x38); //기능셋(데이터버스 8비트, 라인수:2줄)
 
    LCD_cmd_write(0x01);  //화면 지우기
    LCD_cmd_write(0x06);  //엔트리모드셋
    LCD_cmd_write(0x0C);  //표시 On
}
 
void exint0_setting(void){
    EICRA = 0x02;
    EIMSK = 0x01;
} 
 
void init_system(void){
    DDRA = 0xff;
    DDRB = 0xff;
    DDRC = 0xff;
    DDRD = 0x00;
    DDRE = 0xff;
    DDRF = 0xff;
    PORTA = 0xff;   
    PORTB = 0xff;
    PORTC = 0xff;
    PORTE = 0x00;
    PORTF = 0x00;
}
 
void main(void)
{   
    char line1[17] = &quot;                &quot;; 
    char line2[17] = &quot;                &quot;;    
    init_system();
    init_LCD();
    exint0_setting();
                           
    #asm(&quot;sei&quot;); //interrupt enable      
                           
    while (1){
        while(k == -1){
            LCD_wr_string(0x80,&quot;  HURDLE GAME&quot;);
        }     
        
        FND_life();
                 
        line1[15] = generate_hurdle(line1, line2);
        line2[15] = generate_hurdle(line2, line1);
        
        line1[15] = generate_life(line1[15]);
        line2[15] = generate_life(line2[15]);
        
        LCD_display(line1, line2); 
        
        get_life(line1[0], line2[0]);
        
        bump(line1, line2, 1);
        bump(line2, line1, 0);  
        
        move_line(line1, line2);
        
        count++;
      
        level_up();

        delay_ms(50);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;CMD_WRITE&lt;/b&gt; &lt;b&gt;:&lt;/b&gt; LCD에 명령어를 쓰기 위해 PORTA에 할당할 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DATA_WRITE&lt;/b&gt; &lt;b&gt;:&lt;/b&gt; LCD에 데이터를 쓰기 위해 PORTA에 할당할 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LCD_EN&lt;/b&gt; &lt;b&gt;:&lt;/b&gt; PORTA에 할당된 값들과 XOR 연산할 값이다. (E에 클럭을 일으키기 위함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;i, k, count, leve, life, position[2]&lt;/b&gt;&amp;nbsp;&lt;b&gt;:&lt;/b&gt;&amp;nbsp;프로그램에서 사용될 변수들이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 함수에서 사용하기 위해 전역변수로 선언하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;fnd_sel[4] :&lt;/b&gt; PORTF에 할당하여 FND에 숫자를 번갈아 가며 출력하기 위해 선언한 변수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;fnd_data[16] :&lt;/b&gt; PORTC에 할당하여 FND에 숫자를 출력하기 위해 선언한 변수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LCD_cmd_write :&lt;/b&gt; LCD에 명령어를 쓰기 위한 함수로, cmd (실행할 명령어)를 파라미터로 넘겨받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 PORTA에 CMD_WRITE를 할당한 후 PORTB에 cmd (넘겨받은 명령어)를 할당한다. 그 후 PORTA(CMD_WRITE)와 LCD_EN XOR 연산한 값을PORTA에 할당한다. 이 때 PORTA는 0b11111100 -&amp;gt; 0b11111000 으로&amp;nbsp;바뀌며&amp;nbsp;LCD의&amp;nbsp;E단자에&amp;nbsp;클럭이&amp;nbsp;발생하여&amp;nbsp;PORTB에&amp;nbsp;할당된&amp;nbsp;명령어가&amp;nbsp;실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LCD_data_write :&lt;/b&gt; LCD에 데이터를 나타내기 위한 함수로, data(나타낼 데이터) 를 파라미터로 넘겨받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 PORTA에&amp;nbsp; DATA_WRITE를 할당한 후 PORTB에 data(넘겨받은 데이터)를 할당한다. 그 후 PORTA(DATA_WRITE)와 LCD_EN을 XOR 연산한 값을 PORTA에 할당한다. 이 때 PORTA는 0b11111101 -&amp;gt; 0b11111001 로 바뀌며 LCD의 E단자에 클럭이 발생하여 PORTB에 할당된 데이터가 LCD에 나타난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LCD_wr_string :&lt;/b&gt; LCD에 문자열을 나타내기 위한 함수로, 커서 위치를 설정하는 커맨드와 문자열의 첫글자의 주소를 파라미터로 넘겨 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 앞서 선언한 LCD_cmd_write 함수로 넘겨받은 명령어를 실행하여 커서 위치를 설정한다. 그 후 while 문에서 넘겨받은 주솟값을 1씩 증가시키며 주소에 담긴 값을 LCD_data_write 함수를 사용하여 LCD에 나타낸다. 이 때 데이터는 설정된 커서 위치에서 오른쪽으로 옮겨가며 나타난다. 주소에 담긴 값이 \0이면 while문에서&amp;nbsp;빠져나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FND_score :&lt;/b&gt; FND에 점수를 출력하기 위한 함수로, score(게임의 점수)를 파라미터로 넘겨받는다. 게임이 종료되었을 때 while문에서 반복해서 사용될 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 temp를 선언하여 넘겨받은 score를 할당한다. 또한 temp의 각 자릿값을 할당할 fnd를 배열로 선언하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 for문에서 i를 0부터 3까지 증가시키며 fnd[i]에 temp의 각 자리에 해당하는 값을 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 for문에서 i를 0부터 3까지 증가시키며 PORTC에 fnd_data[fnd[i]]를 할당한 후 PORTF에 fnd_sel[i]를 할당한다. FND 의 각 자리에 fnd[i]가 번갈아 가면서 나타나 FND에는 score가 출력되는 것처럼 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FND_life :&lt;/b&gt; FND에 life(게임에서 남은 생명 수)를 출력하기 위한 함수이다. 게임이 진행되는 동안 사용될 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 PORTF에 fnd_sel[1]을 할당한 후 PORTC에 fnd_data[life]를 할당하여 FND의 세 번째 자리에 life를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;generate_hurdle :&lt;/b&gt; 무작위로 장애물을 생성하는 함수이다. 두 문자열의 첫글자의 주소 line1, line2를 파라미터로 넘겨받는다. 이 때 두 문자열은 LCD의 첫 번째 줄과 두 번째 줄에 반복해서 출력되는 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 랜덤값을 level (9와 2 사이의 정수)로 나눈 나머지가 0이면 장애물 '*'를, 0이 아니면 ' '를 리턴한다. 다만 나눈 나머지가 0이라고 해도 앞 두 번 이내의 시도에서 장애물이 생성되었거나 다른 줄의 동일한 시도에서 장애물이 생성되었거나 다른 줄의 이전의 시도에서 장애물이 생성되었다면 ' '를 리턴한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;generate_life :&lt;/b&gt; 생명을 생성하는 함수로, 메인 함수에서 문자 line[15]를 파라미터로 넘겨받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;랜덤값을 200으로 나눈 나머지가 0이면서 life가 8보다 작으면 '+'(생명)를 리턴하고, 이외에는 넘겨받은 문자를 리턴한다. life는 생명 수인데 2로 시작하여 주인공이 장애물과 부딪힐 때마다 1씩 감소하고, 주인공이 '+'를 얻을 때마다 1씩 증가한다. '+'는 life 가 8 이상이면 생성되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LCD_display :&lt;/b&gt; LCD에 문자열을 출력하는 함수이다. 두 문자열의 첫 글자의 주소 line1, line2를 파라미터로 넘겨받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;position[0], position[1]은 앞서 전역변수로 선언한 변수로, LCD의 커서 위치를 설정하는 명령어이다. position[0]는 커서 위치를 두 번째 줄의 가장 왼쪽으로 설정하고, position[1]은 커서 위치를 첫 번째 줄의 가장 왼쪽으로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LCD_wr_string 함수를 사용하여 넘겨받은 주소 line1, line2에 해당하는 문자열을 각각 LCD의 첫 번째, 두 번째 줄에 출력한다. 또한 'o' 를 k값에 따라 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'o'는 게임의 주인공으로 이를 LCD의 첫 번째, 두 번째 줄로 옮겨가며 장애물을 피한다. k는 외부 인터럽트가 발생할 때마다 증가하는 값으로 스위치를 누를 때마다 외부 인터럽트가 발생하여 k가 증가하고, 주인공의 위치가 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;get_life :&lt;/b&gt; 주인공이 생명을 얻으면 life가 증가하고 버저를 울리는 함수이다. 두 문자 life1, life2를 파라미터로 넘겨받는다. life1, life2는 메인함수에서 문자열 line1의 첫 글자, 문자열 line2의 첫 글자이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 line1(LCD의 첫 번째 줄)의 첫 글자가 '+'일 때 k를 2로 나눈 나머지가 1이거나 line2(LCD의 두 번째 줄)의 첫 글자가 '+' 일 때 k를 2로 나눈 나머지가 0이면 (주인공과 생명이 같은 위치에 있으면) life를 증가시키고 FND_life 함수를 사용하여 FND 에 증가한 life 값을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 for 문으로 20ms 동안 PORTE에 16진수 01과 16진수 02를 2ms 간격으로 번갈아가면서 인가한다. 이때 버저에는 교류전류가 흘러 소리가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;bump :&lt;/b&gt; 주인공이 장애물과 부딪히면 life 가 감소하고 버저를 울린 후 life 가 0이 되었다면 LCD에 &quot;GAME OVER&quot; 를 출력하는 함수로, 두 문자열의 첫 글자의 주소 line1, line2 와 정수 position을 파라미터로 넘겨받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 정수형 변수 score를 선언한다. 그 후 주소 line1 에 해당하는 문자가 '*'일 때 k를 2로 나눈 나머지가 positon 이면 (주인공과 장애물이 같은 위치에 있으면) life를 감소시킨 후 FND_life 함수를 사용하여 FND 에 감소된 life 값을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 for 문으로 1초동안 PORTE에 16진수 01과 16진수 02를 2ms 간격으로 번갈아가면서 인가한다. 이 때 버저에는 교류전류가 흘러 소리가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문이 끝나면 k에 position을 할당하여 주인공의 위치를 장애물과 부딪혔을 때의 위치로 놓는다. 소리가 울리는 중에 인터럽트가 발생하여 주인공의 위치가 바뀌는 것을 방지하기 위함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 life가 0이 되었다면 먼저 for문을 사용해 i를 0부터 16까지 증가시키며 line1[i] 와 line2[i]에 빈 칸을 할당한다. for문이 끝나면 LCD_cmd_write 함수로 LCD의 화면클리어 명령어를 실행하여 LCD의 화면을 클리어한다. 그 후에 LCD_wr_string 함수를 사용하여 LCD에 &quot;GAME OVER&quot; 를 출력한다. 또한 앞서 선언한 score에 count 를 할당하고 count, level, life, k를 각각 0, 9, 2, -1로 초기화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후에 while문을 사용하여 k가 -1인 동안 FND_score 함수로 FND에 score를 출력한다. 스위치를 누르면 k가 증가하여 while문에서 빠져나와 게임이 다시 시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;move_line :&lt;/b&gt; 두 문자열의 첫글자의 주소 line1, line2를 파라미터로 넘겨받아 문자열의 문자들을 왼쪽으로 한 칸씩 옮기는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for문에서 i를 0부터 15까지 증가시켜 주소 line1+i, line2+i에 해당하는 문자를 각각 주소 line1+i+1, line2+i+1에 해당하는 문자로 바꾼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;level_up :&lt;/b&gt; count가 100의 배수가 될 때마다 level값을 감소시켜 장애물 발생 확률을 높이는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;count를 100으로 나눈 나머지가 0이면서 level값이 2가&amp;nbsp;아니면&amp;nbsp;level을 1&amp;nbsp;감소시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;interrupt [EXT_INT0] void ext_int0_isr :&lt;/b&gt; 인터럽트가 발생하면 k를 1만큼 증가시키는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;init_LCD :&lt;/b&gt; LCD 설정을 초기화하는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 8비트 인터페이스, 두 줄 표시, 문자 5x7 도트를 설정한다. 화면을 지운 후 커서를 오른쪽으로 이동하면서&amp;nbsp;문자를&amp;nbsp;입력하도록&amp;nbsp;설정한다.&amp;nbsp;마지막으로&amp;nbsp;디스플레이&amp;nbsp;on,&amp;nbsp;커서&amp;nbsp;off,&amp;nbsp;커서&amp;nbsp;깜빡임&amp;nbsp;off를&amp;nbsp;설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;exint0_setting :&lt;/b&gt; 인터럽트 설정을 초기화하는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치 회로를 PD0에 연결하였고 스위치를 누르는 순간 PD0의 전압레벨은 하강에지이기 때문에 EICRA에 16진수 02를 할당하여 PD0의 전압레벨이 하강에지인 순간 인터럽트가 발생하게 하였다. 또한 EIMSK에 16진수 01 을 할당하여 INTO를 활성화시켰다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;init_system :&lt;/b&gt; 시스템을 초기화하는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포트 A, B, C, E, F를 출력으로 사용하였고 포트 D를 입력으로 사용하였다. 포트 A, B, C 에 16진수 FF를 할당하였고 포트 E, F 에 16진수 00 을 할당하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;main : &lt;/b&gt;메인 함수이다. 먼저 문자형 배열 line1, line2를 선언하였고 모두 빈 칸을 할당하였다. init_system 함수로 시스템을 초기화하고 init_LCD 함수로 LCD 설정을 초기화하고 exint0_setting 함수로 인터럽트 설정을 초기화하였다. 그 후 인터럽트를 활성화하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;while문 안에서는 while문으로 k가 -1인동안 LCD에 &quot;HURDLE GAME&quot; 을 출력한다. 스위치를 눌러 인터럽트가 발생하면 k가 증가하여 while 문에서 빠져나오고, 게임이 시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임이 시작되면 먼저 generate_hurdle 함수를 사용하여 line1[15] 와 line2[15]에무작위로 '*' 혹은 ' '를 할당한다. 또한 generate_life 함수를 사용하여 line1[15], line2[15] 에 무작위로 linel[15], line2[15] 혹은 '+'를 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후 LCD_display 함수를 사용하여 LCD에 line1, line2 와 주인공 'o'을 출력한다. &lt;br /&gt;get_life&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;'o'와&amp;nbsp;'+'의&amp;nbsp;위치가&amp;nbsp;같은지&amp;nbsp;판단하고,&amp;nbsp;같으면&amp;nbsp;life를&amp;nbsp;증가시킨&amp;nbsp;후&amp;nbsp;버저를&amp;nbsp;울린다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bump 함수를 사용하여 'o'와 '*'의 위치가 같은지 판단하고, 같으면 life를 감소시킨 후 버저를 울린다. 만약 life 가 0이라면 값들을 초기화한 후 LCD에 &quot;GAME OVER&quot; 를 출력한다. &lt;br /&gt;move_line 함수를 사용하여 문자열의 문자들을 왼쪽으로 한 칸씩 옮긴다. count를 증가시킨 후 level_up 함수를 사용하여 count가 100의 배수일 때마다 level 값을 1씩 감소시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;50ms의 딜레이 이후에 다시 while 문의 처음으로 돌아간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;- 게임 플레이 영상&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=75lE06dlfdM&quot;&gt;https://www.youtube.com/watch?v=75lE06dlfdM&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=75lE06dlfdM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/Xe3sA/hyP0C8sIDI/aTHey7IuAWxijKdhJXCKk1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/75lE06dlfdM&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상으로 보면 장애물의 속도가 약간 느린것 같다. 하지만 실제로 플레이할때 느리다는 느낌은 없으며, 딜레이만 수정하면 빨라질 것이다.&lt;/p&gt;</description>
      <category>공부</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/5</guid>
      <comments>https://jangjy0105.tistory.com/5#entry5comment</comments>
      <pubDate>Mon, 3 Oct 2022 23:59:36 +0900</pubDate>
    </item>
    <item>
      <title>Atmega128 - 장애물 피하기 게임 만들기(1)</title>
      <link>https://jangjy0105.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script data-mce-fragment=&quot;1&quot;&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot; data-mce-fragment=&quot;1&quot;&gt;&lt;/script&gt;
본 포스팅은 작성자가 2021년에 수강했던 마이크로프로세서 강의에 제출한 과제를 바탕으로 작성되었으며, 현재와 문법이 다를 수 있습니다. 또한 학부 수준의 지식으로 작성되었기에 틀린 부분이 존재할 가능성이 다분합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Atmega128을 이용하여 장애물 피하기 게임을 만들 것이다. 게임은 16$\times$2 LCD에 디스플레이 한다. 주인공은 LCD의 가장 왼쪽에 위치하며, 스위치를 누를 때마다 외부 인터럽트를 발생시켜 위, 아래로 이동한다. 장애물은 LCD의 가장 오른쪽에서 생성되어 왼쪽 방향으로 한 칸씩 이동하는데, 스위치를 눌러 주인공을 이동시키며 장애물을 피하는 게임이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; - 게임 진행 설명&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Atmega128에 전원을 연결하면 LCD에 &quot;HURDLE GAME&quot;이라는 문구가 나타난다. 이 때 스위치를 누르면 게임이 시작된다. 처음 생명은 2로 시작하며, 생명은 게임이 진행되는 동안 FND에 표시된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임이 시작되면 스위치를 눌러&amp;nbsp; ' o '로 표시되는 주인공을 위, 아래로 이동시키며 ' * '로 표시되는 장애물을 피해야한다. 장애물과 부딪힌다면 생명이 1 감소하고 1초간 부저가 울린 후 게임이 재개된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임이 진행되면서 장애물의 생성확률은 점점 증가한다. 이외의 요소로 인하여 실제 확률은 더 낮지만 기본적인 확률은 1 라인당 1/9로 시작하며 게임이 진행되면서 최대 1 라인당 1/2 까지 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장애물 뿐만 아니라 생명또한 생성된다. 생명은 ' + '로 표시되며 생명을 얻는다면 생명이 1 증가하고 0.02초간 부저가 울린 후 게임이 재개되는데, 굉장히 짧은 시간이라 부저가 울리는 동안의 정지가 체감이 되진 않는다. 생명의 생성 확률은 1 라인당 1/200로 일정하며, 생명이 8 이상이면 더 이상 생성되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생명이 0이 되면 LCD에 &quot;GAME OVER&quot;라는 문구가 나타나며 FND에 점수가 표시된다. 점수의 기준은 장애물이 한 칸 움직일 때마다 1점씩 증가한다. 또한 &quot;GAME OVER&quot; 화면에서 스위치를 누르면 생명, 장애물 생성확률, 점수가 초기화되며 게임이 재시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;- 인터럽트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;atmega128에는 여러 종류의 인터럽트가 있다. 프로젝트에서 쓰일 인터럽트는 외부 인터럽트인데,&amp;nbsp; atmega128에는 8개의 외부 인터럽트 pin이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 인터럽트를 활성화하기 위해서는 먼저 EIMSK에 값을 할당해야한다. EIMSK에 할당하는 값에 따라 8개의 외부 인터럽트 pin 중 일부만 선택하여 활성화할 수 있는데, 이 프로젝트에서는 PD0에 스위치를 연결하였기 때문에 EIMSK에 16진수 01을 할당하여 &lt;span&gt;INT0만 활성화하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 인터럽트의 발생 순간은 EICRA, EICRB에 값을 할당함으로써 설정한다. EICRA는 INT0, INT1, INT2, INT3의 인터럽트 발생 순간을 설정하고, EICRB는 INT4, INT5, INT6, INT7의 인터럽트 발생 순간을 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터럽트 발생순간은 3가지가 있는데, 전압 레벨이 음(-)일 때, 하강 에지일 때, 상승 에지일 때가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 실험에서는 PD0에 스위치를 연결하였고, 스위치를 누르는 순간의 전압 레벨은 하강 에지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 스위치를 누르는 순간 인터럽트를 발생시키기 위해서는 INT0의 전압 레벨이 하강 에지일 때 인터럽트를 발생시켜야 하므로 EICRA에 16진수 01을 할당하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;- LCD&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cymej2/btrNuiL8S0c/eojDJECeue1SV4RDZq9MIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cymej2/btrNuiL8S0c/eojDJECeue1SV4RDZq9MIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cymej2/btrNuiL8S0c/eojDJECeue1SV4RDZq9MIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcymej2%2FbtrNuiL8S0c%2FeojDJECeue1SV4RDZq9MIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;791&quot; height=&quot;188&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;직접 빛을 내지 않고 외부 입사광을 산란, 간섭, 변조 시키는 소자에 의한 화상 표시장치이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LCD는 VSS(전원 GND), VDD(전원5V), VEE(화면 밝기 조정용 단자), RS(Register Select), R/W(읽기/쓰기 단자), E(Enable), DB0~7(Data Bus), LED A(광원 애노드), LED K(광원&amp;nbsp; 캐소드)로 구성되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중에서 RS, R/W, DB0~7에 코드를 넣어 화면 클리어, 문자 입력 모드, 디스플레이 on/off 제어, DDRAM, CCRAM 주소 설정 등을 동작명령 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; - 피에조 부저&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피에조 부저는 피에조 효과를 이용하여 음파를 발생시키는 장치이다. 피에조 효과란 기계적인 압력을 가하면 전압이 발생하고, 전압을 가하면 기계적인 변형이 발생하는 현상이다. 이를 이용해서 부저에 교류전압을 가하면 진동판이 진동하며 음파를 발생시킬 수 있다. PW신호는 디지털 소스를 사용하여 아날로그 신호를 생성하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피에조 부저에는 능동부저와 수동부저가 있다. 능동부저는 부저에 전원만 공급하면 음파가 발생하며, 지정된 주파수의 음파만 발생된다. 수동부저는 부저에 교류신호를 인가하여야 음파가 발생하며, 인가하는 교류신호의 주파수에 따라 다양한 주파수의 음파가 발생된다. 프로젝트에서 사용할 부저는 수동부저이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; - FND&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;207&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uxN3C/btrNuCqEhTa/F9u68B2dYEbK8HbOjk1esK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uxN3C/btrNuCqEhTa/F9u68B2dYEbK8HbOjk1esK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uxN3C/btrNuCqEhTa/F9u68B2dYEbK8HbOjk1esK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuxN3C%2FbtrNuCqEhTa%2FF9u68B2dYEbK8HbOjk1esK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;207&quot; height=&quot;273&quot; data-origin-width=&quot;207&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FND는 7개의 선분과 1개의 소수점으로 구성되어 있으며, 0~9의 숫자를 표현할 수 있고, 4자리 FND를 활용하여 0~9999까지의 숫자를 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에서 사용할 FND는 공통 애노드 구조이다. 공통 애노드 구조는 공통단자에 양(+)의 전압레벨을 인가하고 a, b, c, d와 같은 조명단다에 음(-)의 전압레벨을 인가하면 전류가 흘러 불이 켜진다. 예를 들어 공통단자에 양의 전압레벨을 인가한 후 a, b, c, d, g에는 음(-) 나머지에는 양(+)의 전압레벨은 인가하면 a, b, c, d, g에 불이 켜지며 숫자 3이 나타난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; - 잔상효과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에서 FND는 0부터 9999까지의 숫자를 나타낼 수 있어야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNXhr4/btrNvwQIoDX/c6kTfpUZHkzqBds9LJZakk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNXhr4/btrNvwQIoDX/c6kTfpUZHkzqBds9LJZakk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNXhr4/btrNvwQIoDX/c6kTfpUZHkzqBds9LJZakk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNXhr4%2FbtrNvwQIoDX%2Fc6kTfpUZHkzqBds9LJZakk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;464&quot; height=&quot;123&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 프로젝트에서 사용될 FND 장치의 회로도인데 A, B, C, D, E, F, G, DP의 단자가 한개씩 밖에 없어서 한 번에 한 가지의 숫자밖에 출력하지 못한다. 다만 각 FND에 숫자를 빠르게 번갈아가며 출력하기를 반복하면 각각 다른 숫자가 계속해서 켜져 있는 것처럼 보인다. 이를 잔상효과라 하는데, 이 프로젝트에서는 잔상효과를 이용하여 0부터 9999까지의 숫자를 나타낼 것이다.&lt;/p&gt;</description>
      <category>공부</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/3</guid>
      <comments>https://jangjy0105.tistory.com/3#entry3comment</comments>
      <pubDate>Fri, 30 Sep 2022 16:45:34 +0900</pubDate>
    </item>
    <item>
      <title>Scilab - 구형 펄스열의 진폭 스펙트럼, 위상 스펙트럼 그리기</title>
      <link>https://jangjy0105.tistory.com/2</link>
      <description>&lt;script&gt; MathJax = { tex: {inlineMath: [['$', '$'], ['\\(', '\\']]} }; &lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅은 작성자가 2020년에 수강했던 수치해석 강의에 제출한 과제를 바탕으로 작성되었으며, 현재의 scilab과 문법이 다를 수 있습니다. 또한 학부 수준의 지식으로 작성되었기에 틀린 부분이 존재할 가능성이 다분합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scilab을 이용하여 T의 주기를 갖고, p의 펄스폭을 갖는 구형 펄스열의 크기와 위상 스펙트럼을 그려볼 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주기를 갖는 함수의 크기와 위상 스펙트럼을 그리기 위해서는 먼저 푸리에계수 Cn을 구해야 하는데 Cn을 구하기 위해 복소푸리에적분을 이용합니다. 복소푸리에적분의 공식은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIM86Q/btrNhCSRmBY/k95NmlHQbTY9ibVf32UX71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIM86Q/btrNhCSRmBY/k95NmlHQbTY9ibVf32UX71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIM86Q/btrNhCSRmBY/k95NmlHQbTY9ibVf32UX71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIM86Q%2FbtrNhCSRmBY%2Fk95NmlHQbTY9ibVf32UX71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;100&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 공식에서 T0는 스펙트럼을 구할 신호의 주기이고, x(t)는 스펙트럼을 구할 신호입니다. 또한 적분구간은 한 주기입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;468&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvTD5D/btrNhDxwZjF/ps2wxmFTojkWWcIkF8oIoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvTD5D/btrNhDxwZjF/ps2wxmFTojkWWcIkF8oIoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvTD5D/btrNhDxwZjF/ps2wxmFTojkWWcIkF8oIoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvTD5D%2FbtrNhDxwZjF%2Fps2wxmFTojkWWcIkF8oIoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;468&quot; height=&quot;448&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;468&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적분의 의미는 위 이미지에서 보시는 바와 같이 피적분함수의 적분구간을 굉장히 작게 쪼갠 후, 쪼갠 부분의 넓이를 모두 더하는 것입니다. 이를 이용하여 scilab에서 Cn을 구할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cn을 구했다면 Cn의 크기와 위상을 구해야 합니다. Cn의 형태는 복소수로, A+jB로 표현할 수 있습니다. A+jB의 크기는 $\sqrt{A^2 + B^2}$ 입니다. 또한 A+jB의 위상은 $tan^{-1}(\frac{B}{A})$입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;849&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2lftv/btrNjp6AxdZ/aTSeiGOJylGspFBrS9Kgh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2lftv/btrNjp6AxdZ/aTSeiGOJylGspFBrS9Kgh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2lftv/btrNjp6AxdZ/aTSeiGOJylGspFBrS9Kgh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2lftv%2FbtrNjp6AxdZ%2FaTSeiGOJylGspFBrS9Kgh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;849&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;849&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 작성한 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 구형 펄스열의 주기 T와 펄스폭 p를 정의 합니다. 또한 기본주파수 w를 $\frac{2&amp;pi;}{T}$로 정의 하고, j를 $\sqrt{-1}$로 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 함수 f(x)는 주기가 T, 펄스폭이 p인 구형 펄스열입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x가 2보다 크면 2보다 작아질 때까지 x에 x-T를 대입합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x가 -2보다 작으면 -2보다 커질 때까지 x에 x+T를 대입합니다. 이제 x의 절댓값이 p/2보다 작으면 1, 크면 0을 반환합니다. 첫 번째 함수의 값은 구형 펄스열의 값과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 함수 Abs(x)는 Cn의 크기를 구하는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r에 복소수 x의 실수부인 real(x)를 대 입하고, i에 복소수 x의 허수부인 imag(x)를 대입합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 복소수 x의 크기인 $\sqrt{r^2+i^2}$이 0.0001보다 작으면 0, 크면 복소수 x의 크기인 $\sqrt{r^2+i^2}$을 반환합니다. (출력이 0.000000일 때 앞에 -가 붙는 것을 방지하기 위함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 번째 함수 Angle(x)는 Cn의 위상을 구하는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r에 복소수 x의 실수부인 real(x)를 대입하고, i에 복소수 x의 허수부인 imag(x)를 대입합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 복소수 x의 위상인 $tan^{-1}(\frac{i}{r})$가 0.0001보다 작으면 0, 크면 복소수 x의 위상인 $tan^{-1}(\frac{i}{r})$를 반환합니다. (출력이 0.000000일 때 앞에 -가 붙는 것을 방지하기 위함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 스펙트럼을 구하기 위해 n값에 따른 Cn을 구합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 적분변수의 증가량인 h를 0.002로 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n이 -15부터 15까지일 때의 스펙트럼을 구하기 위해 for문을 이용하여 n을 -15부터 15까지 증가시켜줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 for문 안에서 sum에 0을 대입하고 Cn을 구하기 위한 for문을 시작합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 for문은 적분변수 t를 0부터 T까지 구형 펄스열의 한 주기동안 h만큼 증가시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 for문 안에서는 sum에 피적분함수 f(t)*exp(-j*n*w*t)/T를 h만큼 쪼갠 조각의 넓이인 h*f(t)*exp(-j*n*w*t)/T를 계속해서 더해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 for문이 끝난 후에 sum은 Cn과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 함수 Abs와 Angle을 이용하여 sum 의 크기와 위상을 출력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 plot을 이용해 주파수값(n*w)에 따른 크기와 위상을 각각 빨간색 과 파란색으로 표시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 작업을 n을 -15부터 15까지 증가시키며 반복하여 진폭 스펙트럼과 위상 스펙트럼을 그립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q7Ewx/btrNk9hO9L5/YA2Wk66P5EFKvCzKnLERn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q7Ewx/btrNk9hO9L5/YA2Wk66P5EFKvCzKnLERn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q7Ewx/btrNk9hO9L5/YA2Wk66P5EFKvCzKnLERn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq7Ewx%2FbtrNk9hO9L5%2FYA2Wk66P5EFKvCzKnLERn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;383&quot; height=&quot;683&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력은 위와 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dy0fuh/btrNiNtbG8L/gRNV1YCS1xBpHbwVTKMtRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dy0fuh/btrNiNtbG8L/gRNV1YCS1xBpHbwVTKMtRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dy0fuh/btrNiNtbG8L/gRNV1YCS1xBpHbwVTKMtRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdy0fuh%2FbtrNiNtbG8L%2FgRNV1YCS1xBpHbwVTKMtRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;878&quot; height=&quot;443&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스펙트럼은 위와 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>공부</category>
      <author>짱구핑구</author>
      <guid isPermaLink="true">https://jangjy0105.tistory.com/2</guid>
      <comments>https://jangjy0105.tistory.com/2#entry2comment</comments>
      <pubDate>Thu, 29 Sep 2022 13:45:01 +0900</pubDate>
    </item>
  </channel>
</rss>